mirror of
https://github.com/tnb-labs/panel.git
synced 2026-09-01 04:17:20 +08:00
Compare commits
93 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 96806d4e94 | |||
| 3de78c95bf | |||
| 367348e688 | |||
| 07dfcd778c | |||
| 789d5e7ddd | |||
| 1102aba9a3 | |||
| fddb076136 | |||
| b1ff8fff3d | |||
| 5cd68fcdc3 | |||
| 3a5ff9179a | |||
| fa7c54ada5 | |||
| 94047174d1 | |||
| 305777f65a | |||
| d56d3ec1dd | |||
| 8ac8da7914 | |||
| 5d56663b69 | |||
| 7ff574cb92 | |||
| 00b4153a28 | |||
| 9412b31279 | |||
| bbf04c91cf | |||
| 252456a1cd | |||
| 8de68b317d | |||
| 8bf273e1fd | |||
| 32111ecd7a | |||
| 82b8a32133 | |||
| b82c644d81 | |||
| 06bf1b0604 | |||
| 7b29e4546a | |||
| ae6b354a78 | |||
| d96c616c61 | |||
| 213698dd2a | |||
| 39b3c74684 | |||
| b3a1af1001 | |||
| 91b244276a | |||
| b1eefd062d | |||
| 2edf6748e7 | |||
| eac69b8dab | |||
| bb7b641193 | |||
| 3b0aee1967 | |||
| 2ae7f3e458 | |||
| ee0442d159 | |||
| 363b7a55be | |||
| 3437bb2b1f | |||
| 7e000cddc8 | |||
| a18652f134 | |||
| dcd8bb3dd9 | |||
| d62a280fe9 | |||
| c3a7710e6f | |||
| 7f1491f739 | |||
| c96b88548e | |||
| f62b112e1b | |||
| e55e3402e9 | |||
| 48b539b31a | |||
| d35245aa11 | |||
| 7f46dea052 | |||
| 48ed174dc6 | |||
| a5743f94b2 | |||
| 227c5344e3 | |||
| 4c8a88ea03 | |||
| 3503aac2f6 | |||
| 6beda2ea12 | |||
| 4579bf8fa9 | |||
| 002db34b4d | |||
| e276c4f747 | |||
| f5e6219ca4 | |||
| fd92b1d360 | |||
| 5b8289c0b0 | |||
| d8fe050607 | |||
| c0310d916f | |||
| 77ed2d77e1 | |||
| c331143e9e | |||
| 71e75312ff | |||
| 0e5bee4852 | |||
| 036ad9222a | |||
| 39cd5545c5 | |||
| 4568e60133 | |||
| d2f224eaa6 | |||
| c77713b3d9 | |||
| f1e2ba5c35 | |||
| 243a36f41c | |||
| 74f772b705 | |||
| e8f1ed5dec | |||
| 634d8c643b | |||
| 1829b46466 | |||
| 478efa5016 | |||
| 841e0e351f | |||
| 0e9761f975 | |||
| 5c067e28b7 | |||
| 0a0e0bcac1 | |||
| c3732b904d | |||
| 161370ac5a | |||
| 0cfe585ad5 | |||
| 283d9dbe26 |
+1
-1
@@ -1,4 +1,4 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
open_collective: haozi-panel
|
||||
open_collective: tnb
|
||||
custom: ['https://afdian.net/a/TheTNB']
|
||||
|
||||
@@ -17,10 +17,8 @@ jobs:
|
||||
go-version: '1.22'
|
||||
cache: false
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
skip-cache: true
|
||||
skip-pkg-cache: true
|
||||
skip-build-cache: true
|
||||
version: latest
|
||||
args: --timeout=30m ./...
|
||||
|
||||
+3
-1
@@ -78,7 +78,7 @@ release:
|
||||
- build
|
||||
- fetch
|
||||
image:
|
||||
name: goreleaser/goreleaser:nightly
|
||||
name: goreleaser/goreleaser
|
||||
entrypoint: [ '' ]
|
||||
only:
|
||||
- tags
|
||||
@@ -87,4 +87,6 @@ release:
|
||||
# generate a changelog.
|
||||
GIT_DEPTH: 0
|
||||
script:
|
||||
- sed -i 's/dl-cdn.alpinelinux.org/mirror.sjtu.edu.cn/g' /etc/apk/repositories
|
||||
- apk add --no-cache upx
|
||||
- goreleaser release --clean
|
||||
|
||||
+18
-8
@@ -1,7 +1,7 @@
|
||||
project_name: panel
|
||||
|
||||
builds:
|
||||
-
|
||||
id: panel
|
||||
- id: panel
|
||||
binary: panel
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
@@ -15,36 +15,46 @@ builds:
|
||||
- v2
|
||||
ldflags:
|
||||
- -s -w --extldflags "-static"
|
||||
|
||||
upx:
|
||||
- enabled: true
|
||||
# Filter by build ID.
|
||||
ids: [ panel ]
|
||||
# Compress argument.
|
||||
# Valid options are from '1' (faster) to '9' (better), and 'best'.
|
||||
compress: best
|
||||
# Whether to try LZMA (slower).
|
||||
lzma: true
|
||||
# Whether to try all methods and filters (slow).
|
||||
brute: false
|
||||
|
||||
archives:
|
||||
-
|
||||
id: panel-archive
|
||||
- id: panel-archive
|
||||
builds:
|
||||
- panel
|
||||
format: zip
|
||||
wrap_in_directory: false
|
||||
strip_parent_binary_folder: true
|
||||
strip_binary_directory: true
|
||||
files:
|
||||
- LICENSE
|
||||
- docs/*
|
||||
- public/*
|
||||
- storage/*
|
||||
- database/*
|
||||
- lang/*
|
||||
- scripts/*
|
||||
- panel-example.conf
|
||||
|
||||
gitlab_urls:
|
||||
api: https://git.haozi.net/api/v4/
|
||||
download: https://git.haozi.net
|
||||
|
||||
# set to true if you use a self-signed certificate
|
||||
skip_tls_verify: false
|
||||
|
||||
# set to true if you want to upload to the Package Registry rather than attachments
|
||||
# Only works with GitLab 13.5+
|
||||
#
|
||||
# Since: v1.3
|
||||
use_package_registry: true
|
||||
|
||||
# Set this if you set GITLAB_TOKEN to the value of CI_JOB_TOKEN.
|
||||
#
|
||||
# Since: v1.11
|
||||
|
||||
@@ -57,7 +57,7 @@ CentOS Stream 可使用迁移脚本迁移至支持的系统: [CentOS 8/9 迁移
|
||||
如果你决定继续,请以`root`用户登录服务器,执行以下命令安装面板:
|
||||
|
||||
```shell
|
||||
HAOZI_DL_URL="https://git.haozi.net/opensource/download/-/raw/main/panel"; curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh.checksum.txt && sha256sum -c install_panel.sh.checksum.txt && bash install_panel.sh || echo "Checksum 验证失败,文件可能被篡改,已终止操作"
|
||||
HAOZI_DL_URL="https://dl.cdn.haozi.net/panel"; curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh.checksum.txt && sha256sum -c install_panel.sh.checksum.txt && bash install_panel.sh || echo "Checksum 验证失败,文件可能被篡改,已终止操作"
|
||||
```
|
||||
|
||||
## 卸载面板
|
||||
@@ -67,7 +67,7 @@ HAOZI_DL_URL="https://git.haozi.net/opensource/download/-/raw/main/panel"; curl
|
||||
如果你无法重装系统,请以`root`用户登录服务器,执行以下命令卸载面板:
|
||||
|
||||
```shell
|
||||
HAOZI_DL_URL="https://git.haozi.net/opensource/download/-/raw/main/panel"; curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh.checksum.txt && sha256sum -c uninstall_panel.sh.checksum.txt && bash uninstall_panel.sh || echo "Checksum 验证失败,文件可能被篡改,已终止操作"
|
||||
HAOZI_DL_URL="https://dl.cdn.haozi.net/panel"; curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh.checksum.txt && sha256sum -c uninstall_panel.sh.checksum.txt && bash uninstall_panel.sh || echo "Checksum 验证失败,文件可能被篡改,已终止操作"
|
||||
```
|
||||
|
||||
卸载面板前请务必备份好所有数据,提前卸载面板全部插件。卸载后数据将**无法恢复**!
|
||||
@@ -84,13 +84,17 @@ panel
|
||||
|
||||
## 问题反馈
|
||||
|
||||
使用类问题,可在 [鼠片社区](https://forum.haozi.net) 提问或QQ群`@坤坤`寻求 AI 帮助,亦可在群里寻求付费支持。
|
||||
使用类问题,可在 [Moe Tom](https://tom.moe) 提问或寻求 AI 帮助,亦可在群里寻求付费支持。
|
||||
|
||||
面板自身问题,可在 GitHub 的`Issues`页面提交问题反馈,注意[提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md)。
|
||||
|
||||
## 赞助商
|
||||
|
||||
### 资金
|
||||
如果耗子 Linux 面板对你有帮助,欢迎[赞助我们](https://afdian.net/a/TheTNB),感谢以下支持者/赞助商的支持:
|
||||
|
||||
**同时接受云资源赞助,可通过QQ群咨询联系**
|
||||
|
||||
### 服务器
|
||||
|
||||
- [微晓朵](https://www.weixiaoduo.com/)
|
||||
|
||||
@@ -99,17 +103,19 @@ panel
|
||||
- [无畏云加速](https://su.sctes.com/register?code=8st689ujpmm2p)
|
||||
- [盾云CDN](http://cdn.ddunyun.com/)
|
||||
|
||||
### DevOps
|
||||
|
||||
- [JetBrains](https://www.jetbrains.com/)
|
||||
|
||||
**接受云资源和资金赞助,可通过QQ群咨询联系**
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://afdian.net/a/TheTNB">
|
||||
<img alt="sponsors" src="https://github.com/TheTNB/sponsor/blob/main/sponsors.svg?raw=true"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## 贡献者
|
||||
|
||||
这个项目的存在要归功于所有做出贡献的人,参与贡献请先查看贡献代码部分。
|
||||
|
||||
<a href="https://github.com/DevHaoZi" target="_blank"><img src="https://avatars.githubusercontent.com/u/115467771?v=4" width="48" height="48"></a>
|
||||
<a href="https://github.com/TheTNB/panel/graphs/contributors">
|
||||
<img alt="contributors" src="https://contrib.rocks/image?repo=TheTNB/panel"/>
|
||||
</a>
|
||||
|
||||
## Star 历史
|
||||
|
||||
|
||||
+16
-10
@@ -57,7 +57,7 @@ As system versions are constantly updated, we may also terminate support for som
|
||||
If you decide to continue, please log in to the server as `root` user and execute the following command to install the panel:
|
||||
|
||||
```shell
|
||||
HAOZI_DL_URL="https://git.haozi.net/opensource/download/-/raw/main/panel"; curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh.checksum.txt && sha256sum -c install_panel.sh.checksum.txt && bash install_panel.sh || echo "Checksum Verification Failed, File May Have Been Tampered With, Operation Terminated"
|
||||
HAOZI_DL_URL="https://dl.cdn.haozi.net/panel"; curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/install_panel.sh.checksum.txt && sha256sum -c install_panel.sh.checksum.txt && bash install_panel.sh || echo "Checksum Verification Failed, File May Have Been Tampered With, Operation Terminated"
|
||||
```
|
||||
|
||||
## Uninstall Panel
|
||||
@@ -67,7 +67,7 @@ Recommended to back up data and reinstall the system first, so that the system c
|
||||
If you are unable to reinstall the system, log in to the server as the `root` user and execute the following command to uninstall the panel:
|
||||
|
||||
```shell
|
||||
HAOZI_DL_URL="https://git.haozi.net/opensource/download/-/raw/main/panel"; curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh.checksum.txt && sha256sum -c uninstall_panel.sh.checksum.txt && bash uninstall_panel.sh || echo "Checksum Verification Failed, File May Have Been Tampered With, Operation Terminated"
|
||||
HAOZI_DL_URL="https://dl.cdn.haozi.net/panel"; curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh && curl -sSL -O ${HAOZI_DL_URL}/uninstall_panel.sh.checksum.txt && sha256sum -c uninstall_panel.sh.checksum.txt && bash uninstall_panel.sh || echo "Checksum Verification Failed, File May Have Been Tampered With, Operation Terminated"
|
||||
```
|
||||
|
||||
Before uninstalling the panel, please be sure to back up all data and uninstall all panel plugins in advance. The data will **not be recoverable** after uninstallation!
|
||||
@@ -84,13 +84,17 @@ See more usage methods and tips in [Wiki](https://github.com/TheTNB/panel/wiki).
|
||||
|
||||
## Feedback
|
||||
|
||||
For usage issues, you can ask questions in the [HaoZi Community Forum](https://forum.haozi.net) or seek AI help in the QQ group `@坤坤`. You can also seek paid support in the group.
|
||||
For usage issues, you can ask questions in the [Moe Tom](https://tom.moe) or seek AI help. You can also seek paid support in the group.
|
||||
|
||||
For issues with the panel itself, you can submit feedback on the `Issues` page of GitHub. Please note [the wisdom of asking questions](http://www.catb.org/~esr/faqs/smart-questions.html).
|
||||
|
||||
## Sponsor
|
||||
|
||||
### Funding
|
||||
If the HaoZi Linux Panel is helpful to you, welcome to [sponsor us](https://opencollective.com/tnb), thanks to the following supporters/sponsors:
|
||||
|
||||
**Accept cloud resources and financial sponsorship, you can contact us through QQ group**
|
||||
|
||||
### Server
|
||||
|
||||
- [微晓朵](https://www.weixiaoduo.com/)
|
||||
|
||||
@@ -99,17 +103,19 @@ For issues with the panel itself, you can submit feedback on the `Issues` page o
|
||||
- [无畏云加速](https://su.sctes.com/register?code=8st689ujpmm2p)
|
||||
- [盾云CDN](http://cdn.ddunyun.com/)
|
||||
|
||||
### DevOps
|
||||
|
||||
- [JetBrains](https://www.jetbrains.com/)
|
||||
|
||||
**Accept cloud resources and financial sponsorship, you can contact us through QQ group**
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://afdian.net/a/TheTNB">
|
||||
<img alt="sponsors" src="https://github.com/TheTNB/sponsor/blob/main/sponsors.svg?raw=true"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Contributor
|
||||
|
||||
This project owes its existence to all those who have contributed. To contribute, please check the contributed code section first.
|
||||
|
||||
<a href="https://github.com/DevHaoZi" target="_blank"><img src="https://avatars.githubusercontent.com/u/115467771?v=4" width="48" height="48"></a>
|
||||
<a href="https://github.com/TheTNB/panel/graphs/contributors">
|
||||
<img alt="contributors" src="https://contrib.rocks/image?repo=TheTNB/panel"/>
|
||||
</a>
|
||||
|
||||
## Star History
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
|
||||
@@ -25,7 +26,8 @@ func (receiver *CertRenew) Signature() string {
|
||||
|
||||
// Description The console command description.
|
||||
func (receiver *CertRenew) Description() string {
|
||||
return "[面板] 证书续签"
|
||||
ctx := context.Background()
|
||||
return facades.Lang(ctx).Get("commands.panel:cert-renew.description")
|
||||
}
|
||||
|
||||
// Extend The console command extend.
|
||||
@@ -36,7 +38,7 @@ func (receiver *CertRenew) Extend() command.Extend {
|
||||
}
|
||||
|
||||
// Handle Execute the console command.
|
||||
func (receiver *CertRenew) Handle(ctx console.Context) error {
|
||||
func (receiver *CertRenew) Handle(console.Context) error {
|
||||
if internal.Status != internal.StatusNormal {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/gookit/color"
|
||||
@@ -27,7 +28,8 @@ func (receiver *Monitoring) Signature() string {
|
||||
|
||||
// Description The console command description.
|
||||
func (receiver *Monitoring) Description() string {
|
||||
return "[面板] 系统监控"
|
||||
ctx := context.Background()
|
||||
return facades.Lang(ctx).Get("commands.panel:monitoring.description")
|
||||
}
|
||||
|
||||
// Extend The console command extend.
|
||||
@@ -38,7 +40,7 @@ func (receiver *Monitoring) Extend() command.Extend {
|
||||
}
|
||||
|
||||
// Handle Execute the console command.
|
||||
func (receiver *Monitoring) Handle(ctx console.Context) error {
|
||||
func (receiver *Monitoring) Handle(console.Context) error {
|
||||
if internal.Status != internal.StatusNormal {
|
||||
return nil
|
||||
}
|
||||
@@ -51,6 +53,8 @@ func (receiver *Monitoring) Handle(ctx console.Context) error {
|
||||
|
||||
info := tools.GetMonitoringInfo()
|
||||
|
||||
translate := facades.Lang(context.Background())
|
||||
|
||||
// 去除部分数据以减少数据库存储
|
||||
info.Disk = nil
|
||||
for _, cpu := range info.Cpus {
|
||||
@@ -70,7 +74,7 @@ func (receiver *Monitoring) Handle(ctx console.Context) error {
|
||||
})
|
||||
if err != nil {
|
||||
facades.Log().Infof("[面板] 系统监控保存失败: %s", err.Error())
|
||||
color.Redf("[面板] 系统监控保存失败: %s", err.Error())
|
||||
color.Redf(translate.Get("commands.panel:monitoring.fail")+": %s", err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
+145
-141
@@ -1,6 +1,7 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -31,7 +32,8 @@ func (receiver *Panel) Signature() string {
|
||||
|
||||
// Description The console command description.
|
||||
func (receiver *Panel) Description() string {
|
||||
return "[面板] 命令行"
|
||||
ctx := context.Background()
|
||||
return facades.Lang(ctx).Get("commands.panel.description")
|
||||
}
|
||||
|
||||
// Extend The console command extend.
|
||||
@@ -50,74 +52,76 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
arg4 := ctx.Argument(4)
|
||||
arg5 := ctx.Argument(5)
|
||||
|
||||
translate := facades.Lang(context.Background())
|
||||
|
||||
switch action {
|
||||
case "init":
|
||||
var check models.User
|
||||
err := facades.Orm().Query().FirstOrFail(&check)
|
||||
if err == nil {
|
||||
color.Redln("面板已初始化")
|
||||
color.Redln(translate.Get("commands.panel.init.exist"))
|
||||
return nil
|
||||
}
|
||||
|
||||
settings := []models.Setting{{Key: models.SettingKeyName, Value: "耗子 Linux 面板"}, {Key: models.SettingKeyMonitor, Value: "1"}, {Key: models.SettingKeyMonitorDays, Value: "30"}, {Key: models.SettingKeyBackupPath, Value: "/www/backup"}, {Key: models.SettingKeyWebsitePath, Value: "/www/wwwroot"}, {Key: models.SettingKeyVersion, Value: facades.Config().GetString("panel.version")}}
|
||||
err = facades.Orm().Query().Create(&settings)
|
||||
if err != nil {
|
||||
color.Redln("初始化失败")
|
||||
color.Redln(translate.Get("commands.panel.init.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
hash, err := facades.Hash().Make(tools.RandomString(32))
|
||||
if err != nil {
|
||||
color.Redln("初始化失败")
|
||||
color.Redln(translate.Get("commands.panel.init.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
user := services.NewUserImpl()
|
||||
_, err = user.Create("admin", hash)
|
||||
if err != nil {
|
||||
color.Redln("创建管理员失败")
|
||||
color.Redln(translate.Get("commands.panel.init.adminFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("初始化成功")
|
||||
color.Greenln(translate.Get("commands.panel.init.success"))
|
||||
|
||||
case "update":
|
||||
var task models.Task
|
||||
err := facades.Orm().Query().Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).FirstOrFail(&task)
|
||||
if err == nil {
|
||||
color.Redln("当前有任务正在执行,禁止更新")
|
||||
color.Redln(translate.Get("commands.panel.update.taskCheck"))
|
||||
return nil
|
||||
}
|
||||
|
||||
panel, err := tools.GetLatestPanelVersion()
|
||||
if err != nil {
|
||||
color.Redln("获取最新版本失败")
|
||||
color.Redln(translate.Get("commands.panel.update.versionFail"))
|
||||
return err
|
||||
}
|
||||
|
||||
internal.Status = internal.StatusUpgrade
|
||||
if err = tools.UpdatePanel(panel); err != nil {
|
||||
internal.Status = internal.StatusFailed
|
||||
color.Redln("更新失败: " + err.Error())
|
||||
color.Redln(translate.Get("commands.panel.update.fail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
internal.Status = internal.StatusNormal
|
||||
color.Greenln("更新成功")
|
||||
color.Greenln(translate.Get("commands.panel.update.success"))
|
||||
tools.RestartPanel()
|
||||
|
||||
case "getInfo":
|
||||
var user models.User
|
||||
err := facades.Orm().Query().Where("id", 1).FirstOrFail(&user)
|
||||
if err != nil {
|
||||
color.Redln("获取管理员信息失败")
|
||||
color.Redln(translate.Get("commands.panel.getInfo.adminGetFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
password := tools.RandomString(16)
|
||||
hash, err := facades.Hash().Make(password)
|
||||
if err != nil {
|
||||
color.Redln("生成密码失败")
|
||||
color.Redln(translate.Get("commands.panel.getInfo.passwordGenerationFail"))
|
||||
return nil
|
||||
}
|
||||
user.Username = tools.RandomString(8)
|
||||
@@ -128,13 +132,13 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
err = facades.Orm().Query().Save(&user)
|
||||
if err != nil {
|
||||
color.Redln("保存管理员信息失败")
|
||||
color.Redln(translate.Get("commands.panel.getInfo.adminSaveFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Redln("获取面板端口失败")
|
||||
color.Redln(translate.Get("commands.panel.portFail"))
|
||||
return nil
|
||||
}
|
||||
ip, err := tools.GetPublicIP()
|
||||
@@ -146,42 +150,42 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
protocol = "https"
|
||||
}
|
||||
|
||||
color.Greenln("用户名: " + user.Username)
|
||||
color.Greenln("密码: " + password)
|
||||
color.Greenln("面板端口: " + port)
|
||||
color.Greenln("面板入口: " + facades.Config().GetString("http.entrance"))
|
||||
color.Greenln("面板地址: " + protocol + "://" + ip + ":" + port + facades.Config().GetString("http.entrance"))
|
||||
color.Greenln(translate.Get("commands.panel.getInfo.username") + ": " + user.Username)
|
||||
color.Greenln(translate.Get("commands.panel.getInfo.password") + ": " + password)
|
||||
color.Greenln(translate.Get("commands.panel.port") + ": " + port)
|
||||
color.Greenln(translate.Get("commands.panel.entrance") + ": " + facades.Config().GetString("http.entrance"))
|
||||
color.Greenln(translate.Get("commands.panel.getInfo.address") + ": " + protocol + "://" + ip + ":" + port + facades.Config().GetString("http.entrance"))
|
||||
|
||||
case "getPort":
|
||||
port, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_PORT | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Redln("获取面板端口失败")
|
||||
color.Redln(translate.Get("commands.panel.portFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("面板端口: " + port)
|
||||
color.Greenln(translate.Get("commands.panel.port") + ": " + port)
|
||||
|
||||
case "getEntrance":
|
||||
color.Greenln("面板入口: " + facades.Config().GetString("http.entrance"))
|
||||
color.Greenln(translate.Get("commands.panel.entrance") + ": " + facades.Config().GetString("http.entrance"))
|
||||
|
||||
case "deleteEntrance":
|
||||
oldEntrance, err := tools.Exec(`cat /www/panel/panel.conf | grep APP_ENTRANCE | awk -F '=' '{print $2}' | tr -d '\n'`)
|
||||
if err != nil {
|
||||
color.Redln("获取面板入口失败")
|
||||
color.Redln(translate.Get("commands.panel.deleteEntrance.fail"))
|
||||
return nil
|
||||
}
|
||||
if _, err = tools.Exec("sed -i 's!APP_ENTRANCE=" + oldEntrance + "!APP_ENTRANCE=/!g' /www/panel/panel.conf"); err != nil {
|
||||
color.Redln("删除面板入口失败")
|
||||
color.Redln(translate.Get("commands.panel.deleteEntrance.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("删除面板入口成功")
|
||||
color.Greenln(translate.Get("commands.panel.deleteEntrance.success"))
|
||||
|
||||
case "writePlugin":
|
||||
slug := arg1
|
||||
version := arg2
|
||||
if len(slug) == 0 || len(version) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.writePlugin.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -193,31 +197,31 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
color.Redln("写入插件安装状态失败")
|
||||
color.Redln(translate.Get("commands.panel.writePlugin.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("写入插件安装状态成功")
|
||||
color.Greenln(translate.Get("commands.panel.writePlugin.success"))
|
||||
|
||||
case "deletePlugin":
|
||||
slug := arg1
|
||||
if len(slug) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.deletePlugin.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := facades.Orm().Query().Where("slug", slug).Delete(&models.Plugin{})
|
||||
if err != nil {
|
||||
color.Redln("移除插件安装状态失败")
|
||||
color.Redln(translate.Get("commands.panel.deletePlugin.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("移除插件安装状态成功")
|
||||
color.Greenln(translate.Get("commands.panel.deletePlugin.success"))
|
||||
|
||||
case "writeMysqlPassword":
|
||||
password := arg1
|
||||
if len(password) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.writeMysqlPassword.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -229,20 +233,20 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
color.Redln("写入MySQL root密码失败")
|
||||
color.Redln(translate.Get("commands.panel.writeMysqlPassword.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("写入MySQL root密码成功")
|
||||
color.Greenln(translate.Get("commands.panel.writeMysqlPassword.success"))
|
||||
|
||||
case "cleanTask":
|
||||
_, err := facades.Orm().Query().Model(&models.Task{}).Where("status", models.TaskStatusRunning).OrWhere("status", models.TaskStatusWaiting).Update("status", models.TaskStatusFailed)
|
||||
if err != nil {
|
||||
color.Redln("清理任务失败")
|
||||
color.Redln(translate.Get("commands.panel.cleanTask.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("清理任务成功")
|
||||
color.Greenln(translate.Get("commands.panel.cleanTask.success"))
|
||||
|
||||
case "backup":
|
||||
backupType := arg1
|
||||
@@ -251,37 +255,37 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
save := arg4
|
||||
hr := `+----------------------------------------------------`
|
||||
if len(backupType) == 0 || len(name) == 0 || len(path) == 0 || len(save) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.backup.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln(hr)
|
||||
color.Greenln("★ 开始备份 [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln("★ " + translate.Get("commands.panel.backup.start") + " [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln(hr)
|
||||
|
||||
if !tools.Exists(path) {
|
||||
if err := tools.Mkdir(path, 0644); err != nil {
|
||||
color.Redln("|-创建备份目录失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.backupDirFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
switch backupType {
|
||||
case "website":
|
||||
color.Yellowln("|-目标网站: " + name)
|
||||
color.Yellowln("|-" + translate.Get("commands.panel.backup.targetSite") + ": " + name)
|
||||
var website models.Website
|
||||
if err := facades.Orm().Query().Where("name", name).FirstOrFail(&website); err != nil {
|
||||
color.Redln("|-网站不存在")
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.siteNotExist"))
|
||||
color.Greenln(hr)
|
||||
return nil
|
||||
}
|
||||
|
||||
backupFile := path + "/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".zip"
|
||||
if _, err := tools.Exec(`cd '` + website.Path + `' && zip -r '` + backupFile + `' .`); err != nil {
|
||||
color.Redln("|-备份失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.backupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-备份成功")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.backupSuccess"))
|
||||
|
||||
case "mysql":
|
||||
rootPassword := services.NewSettingImpl().Get(models.SettingKeyMysqlRootPassword)
|
||||
@@ -289,81 +293,81 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
|
||||
err := os.Setenv("MYSQL_PWD", rootPassword)
|
||||
if err != nil {
|
||||
color.Redln("|-备份MySQL数据库失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.mysqlBackupFail") + ": " + err.Error())
|
||||
color.Greenln(hr)
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("|-目标MySQL数据库: " + name)
|
||||
color.Greenln("|-开始导出")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.targetMysql") + ": " + name)
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.startExport"))
|
||||
if _, err = tools.Exec(`mysqldump -uroot ` + name + ` > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
color.Redln("|-导出失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-导出成功")
|
||||
color.Greenln("|-开始压缩")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.startCompress"))
|
||||
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
color.Redln("|-压缩失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
if err := tools.Remove("/tmp/" + backupFile); err != nil {
|
||||
color.Redln("|-删除失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-压缩成功")
|
||||
color.Greenln("|-开始移动")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.startMove"))
|
||||
if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil {
|
||||
color.Redln("|-移动失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-移动成功")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
|
||||
_ = os.Unsetenv("MYSQL_PWD")
|
||||
color.Greenln("|-备份成功")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.success"))
|
||||
|
||||
case "postgresql":
|
||||
backupFile := name + "_" + carbon.Now().ToShortDateTimeString() + ".sql"
|
||||
check, err := tools.Exec(`su - postgres -c "psql -l" 2>&1`)
|
||||
if err != nil {
|
||||
color.Redln("|-获取数据库失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.databaseGetFail") + ": " + err.Error())
|
||||
color.Greenln(hr)
|
||||
return nil
|
||||
}
|
||||
if !strings.Contains(check, name) {
|
||||
color.Redln("|-数据库不存在")
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.databaseNotExist"))
|
||||
color.Greenln(hr)
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("|-目标PostgreSQL数据库: " + name)
|
||||
color.Greenln("|-开始导出")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.targetPostgres") + ": " + name)
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.startExport"))
|
||||
if _, err = tools.Exec(`su - postgres -c "pg_dump '` + name + `'" > /tmp/` + backupFile + ` 2>&1`); err != nil {
|
||||
color.Redln("|-导出失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.exportFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-导出成功")
|
||||
color.Greenln("|-开始压缩")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.exportSuccess"))
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.startCompress"))
|
||||
if _, err = tools.Exec("cd /tmp && zip -r " + backupFile + ".zip " + backupFile); err != nil {
|
||||
color.Redln("|-压缩失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.compressFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
if err := tools.Remove("/tmp/" + backupFile); err != nil {
|
||||
color.Redln("|-删除失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.deleteFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-压缩成功")
|
||||
color.Greenln("|-开始移动")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.compressSuccess"))
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.startMove"))
|
||||
if err := tools.Mv("/tmp/"+backupFile+".zip", path+"/"+backupFile+".zip"); err != nil {
|
||||
color.Redln("|-移动失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.moveFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-移动成功")
|
||||
color.Greenln("|-备份成功")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.moveSuccess"))
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.success"))
|
||||
}
|
||||
|
||||
color.Greenln(hr)
|
||||
files, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
color.Redln("|-清理失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
var filteredFiles []os.FileInfo
|
||||
@@ -381,15 +385,15 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
})
|
||||
for i := cast.ToInt(save); i < len(filteredFiles); i++ {
|
||||
fileToDelete := filepath.Join(path, filteredFiles[i].Name())
|
||||
color.Yellowln("|-清理备份: " + fileToDelete)
|
||||
color.Yellowln("|-" + translate.Get("commands.panel.backup.cleanBackup") + ": " + fileToDelete)
|
||||
if err := tools.Remove(fileToDelete); err != nil {
|
||||
color.Redln("|-清理失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.backup.cleanupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
color.Greenln("|-清理完成")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.backup.cleanupSuccess"))
|
||||
color.Greenln(hr)
|
||||
color.Greenln("☆ 备份完成 [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln("☆ " + translate.Get("commands.panel.backup.success") + " [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln(hr)
|
||||
|
||||
case "cutoff":
|
||||
@@ -397,44 +401,44 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
save := arg2
|
||||
hr := `+----------------------------------------------------`
|
||||
if len(name) == 0 || len(save) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.cutoff.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln(hr)
|
||||
color.Greenln("★ 开始切割 [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln("★ " + translate.Get("commands.panel.cutoff.start") + " [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln(hr)
|
||||
|
||||
color.Yellowln("|-目标网站: " + name)
|
||||
color.Yellowln("|-" + translate.Get("commands.panel.cutoff.targetSite") + ": " + name)
|
||||
var website models.Website
|
||||
if err := facades.Orm().Query().Where("name", name).FirstOrFail(&website); err != nil {
|
||||
color.Redln("|-网站不存在")
|
||||
color.Redln("|-" + translate.Get("commands.panel.cutoff.siteNotExist"))
|
||||
color.Greenln(hr)
|
||||
return nil
|
||||
}
|
||||
|
||||
logPath := "/www/wwwlogs/" + website.Name + ".log"
|
||||
if !tools.Exists(logPath) {
|
||||
color.Redln("|-日志文件不存在")
|
||||
color.Redln("|-" + translate.Get("commands.panel.cutoff.logNotExist"))
|
||||
color.Greenln(hr)
|
||||
return nil
|
||||
}
|
||||
|
||||
backupPath := "/www/wwwlogs/" + website.Name + "_" + carbon.Now().ToShortDateTimeString() + ".log.zip"
|
||||
if _, err := tools.Exec(`cd /www/wwwlogs && zip -r ` + backupPath + ` ` + website.Name + ".log"); err != nil {
|
||||
color.Redln("|-备份失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.cutoff.backupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
if _, err := tools.Exec(`echo "" > ` + logPath); err != nil {
|
||||
color.Redln("|-清空失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.cutoff.clearFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
color.Greenln("|-切割成功")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.cutoff.cutSuccess"))
|
||||
|
||||
color.Greenln(hr)
|
||||
files, err := os.ReadDir("/www/wwwlogs")
|
||||
if err != nil {
|
||||
color.Redln("|-清理失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
var filteredFiles []os.FileInfo
|
||||
@@ -452,15 +456,15 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
})
|
||||
for i := cast.ToInt(save); i < len(filteredFiles); i++ {
|
||||
fileToDelete := filepath.Join("/www/wwwlogs", filteredFiles[i].Name())
|
||||
color.Yellowln("|-清理日志: " + fileToDelete)
|
||||
color.Yellowln("|-" + translate.Get("commands.panel.cutoff.clearLog") + ": " + fileToDelete)
|
||||
if err := tools.Remove(fileToDelete); err != nil {
|
||||
color.Redln("|-清理失败: " + err.Error())
|
||||
color.Redln("|-" + translate.Get("commands.panel.cutoff.cleanupFail") + ": " + err.Error())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
color.Greenln("|-清理完成")
|
||||
color.Greenln("|-" + translate.Get("commands.panel.cutoff.cleanupSuccess"))
|
||||
color.Greenln(hr)
|
||||
color.Greenln("☆ 切割完成 [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln("☆ " + translate.Get("commands.panel.cutoff.end") + " [" + carbon.Now().ToDateTimeString() + "]")
|
||||
color.Greenln(hr)
|
||||
|
||||
case "writeSite":
|
||||
@@ -470,19 +474,19 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
php := cast.ToInt(arg4)
|
||||
ssl := cast.ToBool(ctx.Argument(5))
|
||||
if len(name) == 0 || len(path) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.writeSite.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
var website models.Website
|
||||
if err := facades.Orm().Query().Where("name", name).FirstOrFail(&website); err == nil {
|
||||
color.Redln("网站已存在")
|
||||
color.Redln(translate.Get("commands.panel.writeSite.siteExist"))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
color.Redln("网站目录不存在")
|
||||
color.Redln(translate.Get("commands.panel.writeSite.pathNotExist"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -494,32 +498,32 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
Ssl: ssl,
|
||||
})
|
||||
if err != nil {
|
||||
color.Redln("写入网站失败")
|
||||
color.Redln(translate.Get("commands.panel.writeSite.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("写入网站成功")
|
||||
color.Greenln(translate.Get("commands.panel.writeSite.success"))
|
||||
|
||||
case "deleteSite":
|
||||
name := arg1
|
||||
if len(name) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.deleteSite.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := facades.Orm().Query().Where("name", name).Delete(&models.Website{})
|
||||
if err != nil {
|
||||
color.Redln("删除网站失败")
|
||||
color.Redln(translate.Get("commands.panel.deleteSite.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("删除网站成功")
|
||||
color.Greenln(translate.Get("commands.panel.deleteSite.success"))
|
||||
|
||||
case "writeSetting":
|
||||
key := arg1
|
||||
value := arg2
|
||||
if len(key) == 0 || len(value) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.writeSetting.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -530,16 +534,16 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
Value: value,
|
||||
})
|
||||
if err != nil {
|
||||
color.Redln("写入设置失败")
|
||||
color.Redln(translate.Get("commands.panel.writeSetting.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("写入设置成功")
|
||||
color.Greenln(translate.Get("commands.panel.writeSetting.success"))
|
||||
|
||||
case "getSetting":
|
||||
key := arg1
|
||||
if len(key) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.getSetting.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -553,17 +557,17 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
case "deleteSetting":
|
||||
key := arg1
|
||||
if len(key) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.deleteSetting.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := facades.Orm().Query().Where("key", key).Delete(&models.Setting{})
|
||||
if err != nil {
|
||||
color.Redln("删除设置失败")
|
||||
color.Redln(translate.Get("commands.panel.deleteSetting.fail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("删除设置成功")
|
||||
color.Greenln(translate.Get("commands.panel.deleteSetting.success"))
|
||||
|
||||
case "addSite":
|
||||
name := arg1
|
||||
@@ -572,14 +576,14 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
path := arg4
|
||||
php := arg5
|
||||
if len(name) == 0 || len(domain) == 0 || len(port) == 0 || len(path) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.addSite.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
domains := strings.Split(domain, ",")
|
||||
ports := strings.Split(port, ",")
|
||||
if len(domains) == 0 || len(ports) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.addSite.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -595,7 +599,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
if id != 0 {
|
||||
color.Redln("网站名已存在")
|
||||
color.Redln(translate.Get("commands.panel.addSite.siteExist"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -614,12 +618,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("网站添加成功")
|
||||
color.Greenln(translate.Get("commands.panel.addSite.success"))
|
||||
|
||||
case "removeSite":
|
||||
name := arg1
|
||||
if len(name) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.removeSite.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -630,7 +634,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
if id == 0 {
|
||||
color.Redln("网站名不存在")
|
||||
color.Redln(translate.Get("commands.panel.removeSite.siteNotExist"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -639,12 +643,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("网站删除成功")
|
||||
color.Greenln(translate.Get("commands.panel.removeSite.success"))
|
||||
|
||||
case "installPlugin":
|
||||
slug := arg1
|
||||
if len(slug) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.installPlugin.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -654,12 +658,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("任务已提交")
|
||||
color.Greenln(translate.Get("commands.panel.installPlugin.success"))
|
||||
|
||||
case "uninstallPlugin":
|
||||
slug := arg1
|
||||
if len(slug) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.uninstallPlugin.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -669,12 +673,12 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("任务已提交")
|
||||
color.Greenln(translate.Get("commands.panel.uninstallPlugin.success"))
|
||||
|
||||
case "updatePlugin":
|
||||
slug := arg1
|
||||
if len(slug) == 0 {
|
||||
color.Redln("参数错误")
|
||||
color.Redln(translate.Get("commands.panel.updatePlugin.paramFail"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -684,34 +688,34 @@ func (receiver *Panel) Handle(ctx console.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
color.Greenln("任务已提交")
|
||||
color.Greenln(translate.Get("commands.panel.updatePlugin.success"))
|
||||
|
||||
default:
|
||||
color.Yellowln(facades.Config().GetString("panel.name") + "命令行工具 - " + facades.Config().GetString("panel.version"))
|
||||
color.Greenln("请使用以下命令:")
|
||||
color.Greenln("panel update 更新 / 修复面板到最新版本")
|
||||
color.Greenln("panel getInfo 重新初始化面板账号信息")
|
||||
color.Greenln("panel getPort 获取面板访问端口")
|
||||
color.Greenln("panel getEntrance 获取面板访问入口")
|
||||
color.Greenln("panel deleteEntrance 删除面板访问入口")
|
||||
color.Greenln("panel cleanTask 清理面板运行中和等待中的任务[任务卡住时使用]")
|
||||
color.Greenln("panel backup {website/mysql/postgresql} {name} {path} {save_copies} 备份网站 / MySQL数据库 / PostgreSQL数据库到指定目录并保留指定数量")
|
||||
color.Greenln("panel cutoff {website_name} {save_copies} 切割网站日志并保留指定数量")
|
||||
color.Greenln("panel installPlugin {slug} 安装插件")
|
||||
color.Greenln("panel uninstallPlugin {slug} 卸载插件")
|
||||
color.Greenln("panel updatePlugin {slug} 更新插件")
|
||||
color.Greenln("panel addSite {name} {domain} {port} {path} {php} 添加网站[域名和端口用英文逗号分隔]")
|
||||
color.Greenln("panel removeSite {name} 删除网站")
|
||||
color.Redln("以下命令请在开发者指导下使用:")
|
||||
color.Yellowln("panel init 初始化面板")
|
||||
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} 写入网站数据到面板")
|
||||
color.Yellowln("panel deleteSite {name} 删除面板网站数据")
|
||||
color.Yellowln("panel getSetting {name} 获取面板设置数据")
|
||||
color.Yellowln("panel writeSetting {name} {value} 写入 / 更新面板设置数据")
|
||||
color.Yellowln("panel deleteSetting {name} 删除面板设置数据")
|
||||
color.Yellowln(facades.Config().GetString("panel.name") + " - " + translate.Get("commands.panel.tool") + " - " + facades.Config().GetString("panel.version"))
|
||||
color.Greenln(translate.Get("commands.panel.use") + ":")
|
||||
color.Greenln("panel update " + translate.Get("commands.panel.update.description"))
|
||||
color.Greenln("panel getInfo " + translate.Get("commands.panel.getInfo.description"))
|
||||
color.Greenln("panel getPort " + translate.Get("commands.panel.getPort.description"))
|
||||
color.Greenln("panel getEntrance " + translate.Get("commands.panel.getEntrance.description"))
|
||||
color.Greenln("panel deleteEntrance " + translate.Get("commands.panel.deleteEntrance.description"))
|
||||
color.Greenln("panel cleanTask " + translate.Get("commands.panel.cleanTask.description"))
|
||||
color.Greenln("panel backup {website/mysql/postgresql} {name} {path} {save_copies} " + translate.Get("commands.panel.backup.description"))
|
||||
color.Greenln("panel cutoff {website_name} {save_copies} " + translate.Get("commands.panel.cutoff.description"))
|
||||
color.Greenln("panel installPlugin {slug} " + translate.Get("commands.panel.installPlugin.description"))
|
||||
color.Greenln("panel uninstallPlugin {slug} " + translate.Get("commands.panel.uninstallPlugin.description"))
|
||||
color.Greenln("panel updatePlugin {slug} " + translate.Get("commands.panel.updatePlugin.description"))
|
||||
color.Greenln("panel addSite {name} {domain} {port} {path} {php} " + translate.Get("commands.panel.addSite.description"))
|
||||
color.Greenln("panel removeSite {name} " + translate.Get("commands.panel.removeSite.description"))
|
||||
color.Redln(translate.Get("commands.panel.forDeveloper") + ":")
|
||||
color.Yellowln("panel init " + translate.Get("commands.panel.init.description"))
|
||||
color.Yellowln("panel writePlugin {slug} {version} " + translate.Get("commands.panel.writePlugin.description"))
|
||||
color.Yellowln("panel deletePlugin {slug} " + translate.Get("commands.panel.deletePlugin.description"))
|
||||
color.Yellowln("panel writeMysqlPassword {password} " + translate.Get("commands.panel.writeMysqlPassword.description"))
|
||||
color.Yellowln("panel writeSite {name} {status} {path} {php} {ssl} " + translate.Get("commands.panel.writeSite.description"))
|
||||
color.Yellowln("panel deleteSite {name} " + translate.Get("commands.panel.deleteSite.description"))
|
||||
color.Yellowln("panel getSetting {name} " + translate.Get("commands.panel.getSetting.description"))
|
||||
color.Yellowln("panel writeSetting {name} {value} " + translate.Get("commands.panel.writeSetting.description"))
|
||||
color.Yellowln("panel deleteSetting {name} " + translate.Get("commands.panel.deleteSetting.description"))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/goravel/framework/contracts/console"
|
||||
"github.com/goravel/framework/contracts/console/command"
|
||||
"github.com/goravel/framework/facades"
|
||||
@@ -21,7 +23,7 @@ func (receiver *PanelTask) Signature() string {
|
||||
|
||||
// Description The console command description.
|
||||
func (receiver *PanelTask) Description() string {
|
||||
return "[面板] 每日任务"
|
||||
return facades.Lang(context.Background()).Get("commands.panel:task.description")
|
||||
}
|
||||
|
||||
// Extend The console command extend.
|
||||
@@ -32,11 +34,12 @@ func (receiver *PanelTask) Extend() command.Extend {
|
||||
}
|
||||
|
||||
// Handle Execute the console command.
|
||||
func (receiver *PanelTask) Handle(ctx console.Context) error {
|
||||
func (receiver *PanelTask) Handle(console.Context) error {
|
||||
internal.Status = internal.StatusMaintain
|
||||
|
||||
// 优化数据库
|
||||
if _, err := facades.Orm().Query().Exec("VACUUM"); err != nil {
|
||||
internal.Status = internal.StatusFailed
|
||||
facades.Log().Tags("面板", "每日任务").
|
||||
With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -46,6 +49,7 @@ func (receiver *PanelTask) Handle(ctx console.Context) error {
|
||||
|
||||
// 备份面板
|
||||
if err := tools.Archive([]string{"/www/panel"}, "/www/backup/panel/panel-"+carbon.Now().ToShortDateTimeString()+".zip"); err != nil {
|
||||
internal.Status = internal.StatusFailed
|
||||
facades.Log().Tags("面板", "每日任务").
|
||||
With(map[string]any{
|
||||
"error": err.Error(),
|
||||
@@ -55,6 +59,7 @@ func (receiver *PanelTask) Handle(ctx console.Context) error {
|
||||
|
||||
// 清理 7 天前的备份
|
||||
if _, err := tools.Exec(`find /www/backup/panel -mtime +7 -name "*.zip" -exec rm -rf {} \;`); err != nil {
|
||||
internal.Status = internal.StatusFailed
|
||||
facades.Log().Tags("面板", "每日任务").
|
||||
With(map[string]any{
|
||||
"error": err.Error(),
|
||||
|
||||
@@ -2,6 +2,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
)
|
||||
|
||||
// SuccessResponse 通用成功响应
|
||||
@@ -26,14 +27,14 @@ func Success(ctx http.Context, data any) http.Response {
|
||||
// Error 响应错误
|
||||
func Error(ctx http.Context, code int, message string) http.Response {
|
||||
return ctx.Response().Json(code, &ErrorResponse{
|
||||
Message: "错误: " + message,
|
||||
Message: facades.Lang(ctx).Get("messages.mistake") + ": " + message,
|
||||
})
|
||||
}
|
||||
|
||||
// ErrorSystem 响应系统错误
|
||||
func ErrorSystem(ctx http.Context) http.Response {
|
||||
return ctx.Response().Json(http.StatusInternalServerError, &ErrorResponse{
|
||||
Message: "系统内部错误",
|
||||
Message: facades.Lang(ctx).Get("errors.internal"),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
commonrequests "panel/app/http/requests/common"
|
||||
|
||||
requests "panel/app/http/requests/file"
|
||||
"panel/pkg/tools"
|
||||
@@ -80,7 +82,7 @@ func (r *FileController) Content(ctx http.Context) http.Response {
|
||||
return Error(ctx, http.StatusInternalServerError, "目标路径不是文件")
|
||||
}
|
||||
if fileInfo.Size() > 10*1024*1024 {
|
||||
return Error(ctx, http.StatusInternalServerError, "文件大小超过 10M")
|
||||
return Error(ctx, http.StatusInternalServerError, "文件大小超过 10 M,不支持在线编辑")
|
||||
}
|
||||
|
||||
content, err := tools.Read(request.Path)
|
||||
@@ -207,15 +209,15 @@ func (r *FileController) Move(ctx http.Context) http.Response {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if tools.Exists(request.New) && !ctx.Request().InputBool("force") {
|
||||
return Error(ctx, http.StatusForbidden, "目标路径已存在,是否覆盖?")
|
||||
if tools.Exists(request.Target) && !ctx.Request().InputBool("force") {
|
||||
return Error(ctx, http.StatusForbidden, "目标路径"+request.Target+"已存在")
|
||||
}
|
||||
|
||||
if err := tools.Mv(request.Old, request.New); err != nil {
|
||||
if err := tools.Mv(request.Source, request.Target); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
r.setPermission(request.New, 0755, "www", "www")
|
||||
r.setPermission(request.Target, 0755, "www", "www")
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -237,15 +239,15 @@ func (r *FileController) Copy(ctx http.Context) http.Response {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
if tools.Exists(request.New) && !ctx.Request().InputBool("force") {
|
||||
return Error(ctx, http.StatusForbidden, "目标路径已存在,是否覆盖?")
|
||||
if tools.Exists(request.Target) && !ctx.Request().InputBool("force") {
|
||||
return Error(ctx, http.StatusForbidden, "目标路径"+request.Target+"已存在")
|
||||
}
|
||||
|
||||
if err := tools.Cp(request.Old, request.New); err != nil {
|
||||
if err := tools.Cp(request.Source, request.Target); err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
r.setPermission(request.New, 0755, "www", "www")
|
||||
r.setPermission(request.Source, 0755, "www", "www")
|
||||
return Success(ctx, nil)
|
||||
}
|
||||
|
||||
@@ -454,7 +456,8 @@ func (r *FileController) Search(ctx http.Context) http.Response {
|
||||
// @Tags 文件管理
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data query requests.Exist true "request"
|
||||
// @Param data query requests.Exist true "request"
|
||||
// @Param data query commonrequests.Paginate true "request"
|
||||
// @Success 200 {object} SuccessResponse
|
||||
// @Router /panel/file/list [get]
|
||||
func (r *FileController) List(ctx http.Context) http.Response {
|
||||
@@ -464,6 +467,12 @@ func (r *FileController) List(ctx http.Context) http.Response {
|
||||
return sanitize
|
||||
}
|
||||
|
||||
var paginate commonrequests.Paginate
|
||||
paginateSanitize := Sanitize(ctx, &paginate)
|
||||
if paginateSanitize != nil {
|
||||
return paginateSanitize
|
||||
}
|
||||
|
||||
fileInfoList, err := os.ReadDir(request.Path)
|
||||
if err != nil {
|
||||
return Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
@@ -472,17 +481,44 @@ func (r *FileController) List(ctx http.Context) http.Response {
|
||||
var paths []any
|
||||
for _, fileInfo := range fileInfoList {
|
||||
info, _ := fileInfo.Info()
|
||||
stat := info.Sys().(*syscall.Stat_t)
|
||||
|
||||
paths = append(paths, map[string]any{
|
||||
"name": info.Name(),
|
||||
"full": filepath.Join(request.Path, info.Name()),
|
||||
"size": tools.FormatBytes(float64(info.Size())),
|
||||
"mode_str": info.Mode().String(),
|
||||
"mode": fmt.Sprintf("%04o", info.Mode().Perm()),
|
||||
"owner": tools.GetUser(stat.Uid),
|
||||
"group": tools.GetGroup(stat.Gid),
|
||||
"uid": stat.Uid,
|
||||
"gid": stat.Gid,
|
||||
"hidden": tools.IsHidden(info.Name()),
|
||||
"symlink": tools.IsSymlink(info.Mode()),
|
||||
"link": tools.GetSymlink(filepath.Join(request.Path, info.Name())),
|
||||
"dir": info.IsDir(),
|
||||
"modify": carbon.FromStdTime(info.ModTime()).ToDateTimeString(),
|
||||
})
|
||||
}
|
||||
|
||||
return Success(ctx, paths)
|
||||
start := paginate.Limit * (paginate.Page - 1)
|
||||
end := paginate.Limit * paginate.Page
|
||||
if start > len(paths) {
|
||||
start = len(paths)
|
||||
}
|
||||
if end > len(paths) {
|
||||
end = len(paths)
|
||||
}
|
||||
|
||||
paged := paths[start:end]
|
||||
if paged == nil {
|
||||
paged = []any{}
|
||||
}
|
||||
|
||||
return Success(ctx, http.Json{
|
||||
"total": len(paths),
|
||||
"items": paged,
|
||||
})
|
||||
}
|
||||
|
||||
// setPermission
|
||||
|
||||
@@ -1,667 +0,0 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"panel/app/http/controllers"
|
||||
"panel/app/models"
|
||||
"panel/internal"
|
||||
"panel/internal/services"
|
||||
"panel/pkg/tools"
|
||||
)
|
||||
|
||||
type Mysql57Controller struct {
|
||||
setting internal.Setting
|
||||
backup internal.Backup
|
||||
}
|
||||
|
||||
func NewMysql57Controller() *Mysql57Controller {
|
||||
return &Mysql57Controller{
|
||||
setting: services.NewSettingImpl(),
|
||||
backup: services.NewBackupImpl(),
|
||||
}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *Mysql57Controller) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, status)
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (r *Mysql57Controller) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载MySQL失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *Mysql57Controller) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启MySQL服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *Mysql57Controller) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动MySQL服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *Mysql57Controller) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止MySQL服务失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (r *Mysql57Controller) GetConfig(ctx http.Context) http.Response {
|
||||
config, err := tools.Read("/www/server/mysql/conf/my.cnf")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, config)
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (r *Mysql57Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空")
|
||||
}
|
||||
|
||||
if err := tools.Write("/www/server/mysql/conf/my.cnf", config, 0644); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "写入MySQL配置失败")
|
||||
}
|
||||
|
||||
return r.Restart(ctx)
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (r *Mysql57Controller) Load(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
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, 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负载失败")
|
||||
}
|
||||
|
||||
var data []map[string]string
|
||||
expressions := []struct {
|
||||
regex string
|
||||
name string
|
||||
}{
|
||||
{`Uptime\s+\|\s+(\d+)\s+\|`, "运行时间"},
|
||||
{`Queries\s+\|\s+(\d+)\s+\|`, "总查询次数"},
|
||||
{`Connections\s+\|\s+(\d+)\s+\|`, "总连接次数"},
|
||||
{`Com_commit\s+\|\s+(\d+)\s+\|`, "每秒事务"},
|
||||
{`Com_rollback\s+\|\s+(\d+)\s+\|`, "每秒回滚"},
|
||||
{`Bytes_sent\s+\|\s+(\d+)\s+\|`, "发送"},
|
||||
{`Bytes_received\s+\|\s+(\d+)\s+\|`, "接收"},
|
||||
{`Threads_connected\s+\|\s+(\d+)\s+\|`, "活动连接数"},
|
||||
{`Max_used_connections\s+\|\s+(\d+)\s+\|`, "峰值连接数"},
|
||||
{`Key_read_requests\s+\|\s+(\d+)\s+\|`, "索引命中率"},
|
||||
{`Innodb_buffer_pool_reads\s+\|\s+(\d+)\s+\|`, "Innodb索引命中率"},
|
||||
{`Created_tmp_disk_tables\s+\|\s+(\d+)\s+\|`, "创建临时表到磁盘"},
|
||||
{`Open_tables\s+\|\s+(\d+)\s+\|`, "已打开的表"},
|
||||
{`Select_full_join\s+\|\s+(\d+)\s+\|`, "没有使用索引的量"},
|
||||
{`Select_full_range_join\s+\|\s+(\d+)\s+\|`, "没有索引的JOIN量"},
|
||||
{`Select_range_check\s+\|\s+(\d+)\s+\|`, "没有索引的子查询量"},
|
||||
{`Sort_merge_passes\s+\|\s+(\d+)\s+\|`, "排序后的合并次数"},
|
||||
{`Table_locks_waited\s+\|\s+(\d+)\s+\|`, "锁表次数"},
|
||||
}
|
||||
|
||||
for _, expression := range expressions {
|
||||
re := regexp.MustCompile(expression.regex)
|
||||
matches := re.FindStringSubmatch(raw)
|
||||
if len(matches) > 1 {
|
||||
d := map[string]string{"name": expression.name, "value": matches[1]}
|
||||
if expression.name == "发送" || expression.name == "接收" {
|
||||
d["value"] = tools.FormatBytes(cast.ToFloat64(matches[1]))
|
||||
}
|
||||
|
||||
data = append(data, d)
|
||||
}
|
||||
}
|
||||
|
||||
// 索引命中率
|
||||
readRequests := cast.ToFloat64(data[9]["value"])
|
||||
reads := cast.ToFloat64(data[10]["value"])
|
||||
data[9]["value"] = fmt.Sprintf("%.2f%%", readRequests/(reads+readRequests)*100)
|
||||
// Innodb 索引命中率
|
||||
bufferPoolReads := cast.ToFloat64(data[11]["value"])
|
||||
bufferPoolReadRequests := cast.ToFloat64(data[12]["value"])
|
||||
data[10]["value"] = fmt.Sprintf("%.2f%%", bufferPoolReadRequests/(bufferPoolReads+bufferPoolReadRequests)*100)
|
||||
|
||||
return controllers.Success(ctx, data)
|
||||
}
|
||||
|
||||
// ErrorLog 获取错误日志
|
||||
func (r *Mysql57Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
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)
|
||||
}
|
||||
|
||||
// ClearErrorLog 清空错误日志
|
||||
func (r *Mysql57Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
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 获取慢查询日志
|
||||
func (r *Mysql57Controller) SlowLog(ctx http.Context) http.Response {
|
||||
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)
|
||||
}
|
||||
|
||||
// ClearSlowLog 清空慢查询日志
|
||||
func (r *Mysql57Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
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密码
|
||||
func (r *Mysql57Controller) GetRootPassword(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码为空")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, rootPassword)
|
||||
}
|
||||
|
||||
// SetRootPassword 设置root密码
|
||||
func (r *Mysql57Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
}
|
||||
if !status {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "MySQL 未运行")
|
||||
}
|
||||
|
||||
rootPassword := ctx.Request().Input("password")
|
||||
if len(rootPassword) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码不能为空")
|
||||
}
|
||||
|
||||
oldRootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if oldRootPassword != rootPassword {
|
||||
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 {
|
||||
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, nil)
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
func (r *Mysql57Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
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 {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SHOW DATABASES")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var databases []database
|
||||
for rows.Next() {
|
||||
var d database
|
||||
err := rows.Scan(&d.Name)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
databases = append(databases, d)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取数据库列表失败")
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(databases) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []database{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(databases) {
|
||||
endIndex = len(databases)
|
||||
}
|
||||
pagedDatabases := databases[startIndex:endIndex]
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(databases),
|
||||
"items": pagedDatabases,
|
||||
})
|
||||
}
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (r *Mysql57Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
database := ctx.Request().Input("database")
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE DATABASE IF NOT EXISTS " + database + " DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;\""); err != nil {
|
||||
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, nil)
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (r *Mysql57Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP DATABASE IF EXISTS " + database + ";\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
func (r *Mysql57Controller) BackupList(ctx http.Context) http.Response {
|
||||
backupList, err := r.backup.MysqlList()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(backupList) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []internal.BackupFile{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(backupList) {
|
||||
endIndex = len(backupList)
|
||||
}
|
||||
pagedBackupList := backupList[startIndex:endIndex]
|
||||
if pagedBackupList == nil {
|
||||
pagedBackupList = []internal.BackupFile{}
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(backupList),
|
||||
"items": pagedBackupList,
|
||||
})
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (r *Mysql57Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
}
|
||||
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/mysql"
|
||||
if !tools.Exists(backupPath) {
|
||||
if err = tools.Mkdir(backupPath, 0644); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
name := file.GetClientOriginalName()
|
||||
_, err = file.StoreAs(backupPath, name)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (r *Mysql57Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
database := ctx.Request().Input("database")
|
||||
err = r.backup.MysqlBackup(database)
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (r *Mysql57Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
backupPath := r.setting.Get(models.SettingKeyBackupPath) + "/mysql"
|
||||
fileName := ctx.Request().Input("name")
|
||||
if err := tools.Remove(backupPath + "/" + fileName); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (r *Mysql57Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"backup": "required|min_len:1|max_len:255",
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
err = r.backup.MysqlRestore(ctx.Request().Input("database"), ctx.Request().Input("backup"))
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
func (r *Mysql57Controller) UserList(ctx http.Context) http.Response {
|
||||
type user struct {
|
||||
User string `json:"user"`
|
||||
Host string `json:"host"`
|
||||
Grants []string `json:"grants"`
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
db, err := sql.Open("mysql", "root:"+rootPassword+"@unix(/tmp/mysql.sock)/")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("SELECT user, host FROM mysql.user")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var userGrants []user
|
||||
|
||||
for rows.Next() {
|
||||
var u user
|
||||
err := rows.Scan(&u.User, &u.Host)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// 查询用户权限
|
||||
grantsRows, err := db.Query(fmt.Sprintf("SHOW GRANTS FOR '%s'@'%s'", u.User, u.Host))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer grantsRows.Close()
|
||||
|
||||
for grantsRows.Next() {
|
||||
var grant string
|
||||
err := grantsRows.Scan(&grant)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
u.Grants = append(u.Grants, grant)
|
||||
}
|
||||
|
||||
if err := grantsRows.Err(); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
userGrants = append(userGrants, u)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取用户列表失败")
|
||||
}
|
||||
|
||||
page := ctx.Request().QueryInt("page", 1)
|
||||
limit := ctx.Request().QueryInt("limit", 10)
|
||||
startIndex := (page - 1) * limit
|
||||
endIndex := page * limit
|
||||
if startIndex > len(userGrants) {
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": 0,
|
||||
"items": []user{},
|
||||
})
|
||||
}
|
||||
if endIndex > len(userGrants) {
|
||||
endIndex = len(userGrants)
|
||||
}
|
||||
pagedUserGrants := userGrants[startIndex:endIndex]
|
||||
|
||||
return controllers.Success(ctx, http.Json{
|
||||
"total": len(userGrants),
|
||||
"items": pagedUserGrants,
|
||||
})
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
func (r *Mysql57Controller) AddUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"CREATE USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + ";'\""); err != nil {
|
||||
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, nil)
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (r *Mysql57Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"DROP USER '" + user + "'@'localhost';\""); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
|
||||
return controllers.Success(ctx, nil)
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (r *Mysql57Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
password := ctx.Request().Input("password")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"ALTER USER '" + user + "'@'localhost' IDENTIFIED BY '" + password + "';\""); err != nil {
|
||||
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, nil)
|
||||
}
|
||||
|
||||
// SetUserPrivileges 设置用户权限
|
||||
func (r *Mysql57Controller) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"database": "required|min_len:1|max_len:255",
|
||||
})
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
if validator.Fails() {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, validator.Errors().One())
|
||||
}
|
||||
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
user := ctx.Request().Input("user")
|
||||
database := ctx.Request().Input("database")
|
||||
if out, err := tools.Exec("/www/server/mysql/bin/mysql -uroot -p" + rootPassword + " -e \"REVOKE ALL PRIVILEGES ON *.* FROM '" + user + "'@'localhost';\""); err != nil {
|
||||
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, nil)
|
||||
}
|
||||
+30
-30
@@ -15,20 +15,20 @@ import (
|
||||
"panel/pkg/tools"
|
||||
)
|
||||
|
||||
type Mysql80Controller struct {
|
||||
type MySQLController struct {
|
||||
setting internal.Setting
|
||||
backup internal.Backup
|
||||
}
|
||||
|
||||
func NewMysql80Controller() *Mysql80Controller {
|
||||
return &Mysql80Controller{
|
||||
func NewMySQLController() *MySQLController {
|
||||
return &MySQLController{
|
||||
setting: services.NewSettingImpl(),
|
||||
backup: services.NewBackupImpl(),
|
||||
}
|
||||
}
|
||||
|
||||
// Status 获取运行状态
|
||||
func (r *Mysql80Controller) Status(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) Status(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
@@ -38,7 +38,7 @@ func (r *Mysql80Controller) Status(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Reload 重载配置
|
||||
func (r *Mysql80Controller) Reload(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) Reload(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceReload("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重载MySQL配置失败")
|
||||
}
|
||||
@@ -47,7 +47,7 @@ func (r *Mysql80Controller) Reload(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Restart 重启服务
|
||||
func (r *Mysql80Controller) Restart(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) Restart(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceRestart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "重启MySQL服务失败")
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func (r *Mysql80Controller) Restart(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (r *Mysql80Controller) Start(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) Start(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStart("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "启动MySQL服务失败")
|
||||
}
|
||||
@@ -65,7 +65,7 @@ func (r *Mysql80Controller) Start(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Stop 停止服务
|
||||
func (r *Mysql80Controller) Stop(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) Stop(ctx http.Context) http.Response {
|
||||
if err := tools.ServiceStop("mysqld"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "停止MySQL服务失败")
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (r *Mysql80Controller) Stop(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// GetConfig 获取配置
|
||||
func (r *Mysql80Controller) GetConfig(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) GetConfig(ctx http.Context) http.Response {
|
||||
config, err := tools.Read("/www/server/mysql/conf/my.cnf")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL配置失败")
|
||||
@@ -84,7 +84,7 @@ func (r *Mysql80Controller) GetConfig(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// SaveConfig 保存配置
|
||||
func (r *Mysql80Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) SaveConfig(ctx http.Context) http.Response {
|
||||
config := ctx.Request().Input("config")
|
||||
if len(config) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "配置不能为空")
|
||||
@@ -98,7 +98,7 @@ func (r *Mysql80Controller) SaveConfig(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// Load 获取负载
|
||||
func (r *Mysql80Controller) Load(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) Load(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码为空")
|
||||
@@ -168,7 +168,7 @@ func (r *Mysql80Controller) Load(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// ErrorLog 获取错误日志
|
||||
func (r *Mysql80Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) ErrorLog(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-error.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
@@ -178,7 +178,7 @@ func (r *Mysql80Controller) ErrorLog(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// ClearErrorLog 清空错误日志
|
||||
func (r *Mysql80Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-error.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -187,7 +187,7 @@ func (r *Mysql80Controller) ClearErrorLog(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// SlowLog 获取慢查询日志
|
||||
func (r *Mysql80Controller) SlowLog(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) SlowLog(ctx http.Context) http.Response {
|
||||
log, err := tools.Exec("tail -n 100 /www/server/mysql/mysql-slow.log")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, log)
|
||||
@@ -197,7 +197,7 @@ func (r *Mysql80Controller) SlowLog(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// ClearSlowLog 清空慢查询日志
|
||||
func (r *Mysql80Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) ClearSlowLog(ctx http.Context) http.Response {
|
||||
if out, err := tools.Exec("echo '' > /www/server/mysql/mysql-slow.log"); err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, out)
|
||||
}
|
||||
@@ -205,7 +205,7 @@ func (r *Mysql80Controller) ClearSlowLog(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// GetRootPassword 获取root密码
|
||||
func (r *Mysql80Controller) GetRootPassword(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) GetRootPassword(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
if len(rootPassword) == 0 {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "MySQL root密码为空")
|
||||
@@ -215,7 +215,7 @@ func (r *Mysql80Controller) GetRootPassword(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// SetRootPassword 设置root密码
|
||||
func (r *Mysql80Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) SetRootPassword(ctx http.Context) http.Response {
|
||||
status, err := tools.ServiceStatus("mysqld")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取MySQL状态失败")
|
||||
@@ -253,7 +253,7 @@ func (r *Mysql80Controller) SetRootPassword(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// DatabaseList 获取数据库列表
|
||||
func (r *Mysql80Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) DatabaseList(ctx http.Context) http.Response {
|
||||
rootPassword := r.setting.Get(models.SettingKeyMysqlRootPassword)
|
||||
type database struct {
|
||||
Name string `json:"name"`
|
||||
@@ -308,7 +308,7 @@ func (r *Mysql80Controller) DatabaseList(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// AddDatabase 添加数据库
|
||||
func (r *Mysql80Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) AddDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
@@ -343,7 +343,7 @@ func (r *Mysql80Controller) AddDatabase(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// DeleteDatabase 删除数据库
|
||||
func (r *Mysql80Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) DeleteDatabase(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
@@ -364,7 +364,7 @@ func (r *Mysql80Controller) DeleteDatabase(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// BackupList 获取备份列表
|
||||
func (r *Mysql80Controller) BackupList(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) BackupList(ctx http.Context) http.Response {
|
||||
backupList, err := r.backup.MysqlList()
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
|
||||
@@ -395,7 +395,7 @@ func (r *Mysql80Controller) BackupList(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// UploadBackup 上传备份
|
||||
func (r *Mysql80Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) UploadBackup(ctx http.Context) http.Response {
|
||||
file, err := ctx.Request().File("file")
|
||||
if err != nil {
|
||||
return controllers.Error(ctx, http.StatusUnprocessableEntity, "上传文件失败")
|
||||
@@ -418,7 +418,7 @@ func (r *Mysql80Controller) UploadBackup(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// CreateBackup 创建备份
|
||||
func (r *Mysql80Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) CreateBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
})
|
||||
@@ -439,7 +439,7 @@ func (r *Mysql80Controller) CreateBackup(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// DeleteBackup 删除备份
|
||||
func (r *Mysql80Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) DeleteBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"name": "required|min_len:1|max_len:255",
|
||||
})
|
||||
@@ -460,7 +460,7 @@ func (r *Mysql80Controller) DeleteBackup(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// RestoreBackup 还原备份
|
||||
func (r *Mysql80Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) RestoreBackup(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"backup": "required|min_len:1|max_len:255",
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$|not_in:information_schema,mysql,performance_schema,sys",
|
||||
@@ -481,7 +481,7 @@ func (r *Mysql80Controller) RestoreBackup(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// UserList 用户列表
|
||||
func (r *Mysql80Controller) UserList(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) UserList(ctx http.Context) http.Response {
|
||||
type user struct {
|
||||
User string `json:"user"`
|
||||
Host string `json:"host"`
|
||||
@@ -560,7 +560,7 @@ func (r *Mysql80Controller) UserList(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// AddUser 添加用户
|
||||
func (r *Mysql80Controller) AddUser(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) AddUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"database": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
@@ -591,7 +591,7 @@ func (r *Mysql80Controller) AddUser(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// DeleteUser 删除用户
|
||||
func (r *Mysql80Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) DeleteUser(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
})
|
||||
@@ -612,7 +612,7 @@ func (r *Mysql80Controller) DeleteUser(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// SetUserPassword 设置用户密码
|
||||
func (r *Mysql80Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) SetUserPassword(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"password": "required|min_len:8|max_len:255",
|
||||
@@ -638,7 +638,7 @@ func (r *Mysql80Controller) SetUserPassword(ctx http.Context) http.Response {
|
||||
}
|
||||
|
||||
// SetUserPrivileges 设置用户权限
|
||||
func (r *Mysql80Controller) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
func (r *MySQLController) SetUserPrivileges(ctx http.Context) http.Response {
|
||||
validator, err := ctx.Request().Validate(map[string]string{
|
||||
"user": "required|min_len:1|max_len:255|regex:^[a-zA-Z][a-zA-Z0-9_]+$",
|
||||
"database": "required|min_len:1|max_len:255",
|
||||
@@ -4,8 +4,8 @@ import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/imroc/req/v3"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"panel/app/http/controllers"
|
||||
@@ -117,9 +117,9 @@ func (r *OpenRestyController) ClearErrorLog(ctx http.Context) http.Response {
|
||||
|
||||
// Load 获取负载
|
||||
func (r *OpenRestyController) Load(ctx http.Context) http.Response {
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
client := resty.New().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/nginx_status")
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
if err != nil || !resp.IsSuccess() {
|
||||
return controllers.Error(ctx, http.StatusInternalServerError, "获取OpenResty负载失败")
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,11 @@ import (
|
||||
// Jwt 确保通过 JWT 鉴权
|
||||
func Jwt() http.Middleware {
|
||||
return func(ctx http.Context) {
|
||||
translate := facades.Lang(ctx)
|
||||
token := ctx.Request().Header("Authorization", ctx.Request().Header("Sec-WebSocket-Protocol"))
|
||||
if len(token) == 0 {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusUnauthorized, http.Json{
|
||||
"message": "未登录",
|
||||
"message": translate.Get("auth.token.missing"),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -26,7 +27,7 @@ func Jwt() http.Middleware {
|
||||
if err != nil {
|
||||
// 到达刷新时间上限
|
||||
ctx.Request().AbortWithStatusJson(http.StatusUnauthorized, http.Json{
|
||||
"message": "登录已过期",
|
||||
"message": translate.Get("auth.token.expired"),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -34,7 +35,7 @@ func Jwt() http.Middleware {
|
||||
token = "Bearer " + token
|
||||
} else {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusUnauthorized, http.Json{
|
||||
"message": "登录已过期",
|
||||
"message": translate.Get("auth.token.expired"),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/contracts/translation"
|
||||
"github.com/goravel/framework/facades"
|
||||
|
||||
"panel/internal/services"
|
||||
)
|
||||
@@ -12,6 +14,7 @@ import (
|
||||
func MustInstall() http.Middleware {
|
||||
return func(ctx http.Context) {
|
||||
path := ctx.Request().Path()
|
||||
translate := facades.Lang(ctx)
|
||||
var slug string
|
||||
if strings.HasPrefix(path, "/api/panel/website") {
|
||||
slug = "openresty"
|
||||
@@ -19,7 +22,7 @@ func MustInstall() http.Middleware {
|
||||
pathArr := strings.Split(path, "/")
|
||||
if len(pathArr) < 4 {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
|
||||
"message": "插件不存在",
|
||||
"message": translate.Get("errors.plugin.notExist"),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -31,14 +34,18 @@ func MustInstall() http.Middleware {
|
||||
installedPlugins, err := services.NewPluginImpl().AllInstalled()
|
||||
if err != nil {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusInternalServerError, http.Json{
|
||||
"message": "系统内部错误",
|
||||
"message": translate.Get("errors.internal"),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if installedPlugin.Slug != plugin.Slug {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
|
||||
"message": "插件 " + slug + " 未安装",
|
||||
"message": translate.Get("errors.plugin.notInstalled", translation.Option{
|
||||
Replace: map[string]string{
|
||||
"slug": slug,
|
||||
},
|
||||
}),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -53,7 +60,12 @@ func MustInstall() http.Middleware {
|
||||
_, requireFound := pluginsMap[require]
|
||||
if !requireFound {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
|
||||
"message": "插件 " + slug + " 需要依赖 " + require + " 插件",
|
||||
"message": translate.Get("errors.plugin.dependent", translation.Option{
|
||||
Replace: map[string]string{
|
||||
"slug": slug,
|
||||
"dependency": require,
|
||||
},
|
||||
}),
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -63,7 +75,12 @@ func MustInstall() http.Middleware {
|
||||
_, excludeFound := pluginsMap[exclude]
|
||||
if excludeFound {
|
||||
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
|
||||
"message": "插件 " + slug + " 不兼容 " + exclude + " 插件",
|
||||
"message": translate.Get("errors.plugin.incompatible", translation.Option{
|
||||
Replace: map[string]string{
|
||||
"slug": slug,
|
||||
"exclude": exclude,
|
||||
},
|
||||
}),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package middleware
|
||||
|
||||
import (
|
||||
"github.com/goravel/framework/contracts/http"
|
||||
"github.com/goravel/framework/facades"
|
||||
|
||||
"panel/internal"
|
||||
)
|
||||
@@ -9,25 +10,26 @@ import (
|
||||
// Status 检查程序状态
|
||||
func Status() http.Middleware {
|
||||
return func(ctx http.Context) {
|
||||
translate := facades.Lang(ctx)
|
||||
switch internal.Status {
|
||||
case internal.StatusUpgrade:
|
||||
ctx.Request().AbortWithStatusJson(http.StatusServiceUnavailable, http.Json{
|
||||
"message": "面板升级中,请稍后",
|
||||
"message": translate.Get("status.upgrade"),
|
||||
})
|
||||
return
|
||||
case internal.StatusMaintain:
|
||||
ctx.Request().AbortWithStatusJson(http.StatusServiceUnavailable, http.Json{
|
||||
"message": "面板正在运行维护,请稍后",
|
||||
"message": translate.Get("status.maintain"),
|
||||
})
|
||||
return
|
||||
case internal.StatusClosed:
|
||||
ctx.Request().AbortWithStatusJson(http.StatusForbidden, http.Json{
|
||||
"message": "面板已关闭",
|
||||
"message": translate.Get("status.closed"),
|
||||
})
|
||||
return
|
||||
case internal.StatusFailed:
|
||||
ctx.Request().AbortWithStatusJson(http.StatusInternalServerError, http.Json{
|
||||
"message": "面板运行出错,请检查排除或联系支持",
|
||||
"message": translate.Get("status.failed"),
|
||||
})
|
||||
return
|
||||
default:
|
||||
|
||||
@@ -17,8 +17,8 @@ func (r *Archive) Authorize(ctx http.Context) error {
|
||||
func (r *Archive) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"paths": "array",
|
||||
"paths.*": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"file": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_not_exists",
|
||||
"paths.*": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"file": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_not_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
)
|
||||
|
||||
type Copy struct {
|
||||
Old string `form:"old" json:"old"`
|
||||
New string `form:"new" json:"new"`
|
||||
Source string `form:"source" json:"source"`
|
||||
Target string `form:"target" json:"target"`
|
||||
}
|
||||
|
||||
func (r *Copy) Authorize(ctx http.Context) error {
|
||||
@@ -16,8 +16,8 @@ func (r *Copy) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Copy) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"old": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"new": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$",
|
||||
"source": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"target": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ func (r *Exist) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Exist) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"path": `regex:^/([a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*)?$|path_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
)
|
||||
|
||||
type Move struct {
|
||||
Old string `form:"old" json:"old"`
|
||||
New string `form:"new" json:"new"`
|
||||
Source string `form:"source" json:"source"`
|
||||
Target string `form:"target" json:"target"`
|
||||
}
|
||||
|
||||
func (r *Move) Authorize(ctx http.Context) error {
|
||||
@@ -16,8 +16,8 @@ func (r *Move) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Move) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"old": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"new": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$",
|
||||
"source": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"target": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ func (r *NotExist) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *NotExist) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_not_exists",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_not_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func (r *Permission) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Permission) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"mode": "regex:^[0-7]{3}$|uint",
|
||||
"owner": "regex:^[a-zA-Z0-9_-]+$",
|
||||
"group": "regex:^[a-zA-Z0-9_-]+$",
|
||||
|
||||
@@ -16,7 +16,7 @@ func (r *Save) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Save) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"content": "required|string",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func (r *Search) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Search) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"keyword": "required|string",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ func (r *UnArchive) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *UnArchive) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"file": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_exists",
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$|path_not_exists",
|
||||
"file": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_exists`,
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$|path_not_exists`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func (r *Upload) Authorize(ctx http.Context) error {
|
||||
|
||||
func (r *Upload) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"file": "required",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func (r *Create) Authorize(ctx http.Context) error {
|
||||
func (r *Create) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"comment": "string",
|
||||
"auth_user": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"secret": "required|min_len:8",
|
||||
|
||||
@@ -21,7 +21,7 @@ func (r *Update) Authorize(ctx http.Context) error {
|
||||
func (r *Update) Rules(ctx http.Context) map[string]string {
|
||||
return map[string]string{
|
||||
"name": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"path": "regex:^/[a-zA-Z0-9_.@#$%-]+(\\/[a-zA-Z0-9_.@#$%-]+)*$",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"comment": "string",
|
||||
"auth_user": "required|regex:^[a-zA-Z0-9-_]+$",
|
||||
"secret": "required|min_len:8",
|
||||
|
||||
@@ -27,7 +27,7 @@ func (r *Add) Rules(ctx http.Context) map[string]string {
|
||||
"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_.@#$%-]+)*$",
|
||||
"path": `regex:^/[a-zA-Z0-9_.@#$%\-\s\[\]()]+(/[a-zA-Z0-9_.@#$%\-\s\[\]()]+)*$`,
|
||||
"php": "required",
|
||||
"db": "bool",
|
||||
"db_type": "required_if:db,true|in:0,mysql,postgresql",
|
||||
|
||||
+3
-1
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/goravel/framework/schedule"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
"github.com/goravel/framework/testing"
|
||||
"github.com/goravel/framework/translation"
|
||||
"github.com/goravel/framework/validation"
|
||||
"github.com/goravel/gin"
|
||||
|
||||
@@ -60,7 +61,7 @@ func init() {
|
||||
// The application locale determines the default locale that will be used
|
||||
// by the translation service provider.You are free to set this value
|
||||
// to any of the locales which will be supported by the application.
|
||||
"locale": "zh_CN",
|
||||
"locale": config.Env("APP_LOCALE", "zh_CN"),
|
||||
|
||||
// Application Fallback Locale
|
||||
//
|
||||
@@ -96,6 +97,7 @@ func init() {
|
||||
&crypt.ServiceProvider{},
|
||||
&filesystem.ServiceProvider{},
|
||||
&validation.ServiceProvider{},
|
||||
&translation.ServiceProvider{},
|
||||
&testing.ServiceProvider{},
|
||||
&providers.AppServiceProvider{},
|
||||
&providers.AuthServiceProvider{},
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ func init() {
|
||||
config := facades.Config()
|
||||
config.Add("panel", map[string]any{
|
||||
"name": "耗子 Linux 面板",
|
||||
"version": "v2.1.44",
|
||||
"version": "v2.2.3",
|
||||
"ssl": config.Env("APP_SSL", false),
|
||||
})
|
||||
}
|
||||
|
||||
+12
-2
@@ -2339,6 +2339,16 @@ const docTemplate = `{
|
||||
"type": "string",
|
||||
"name": "path",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -4373,10 +4383,10 @@ const docTemplate = `{
|
||||
"requests.Move": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"new": {
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"old": {
|
||||
"target": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
||||
+12
-2
@@ -2332,6 +2332,16 @@
|
||||
"type": "string",
|
||||
"name": "path",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "limit",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "page",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -4366,10 +4376,10 @@
|
||||
"requests.Move": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"new": {
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"old": {
|
||||
"target": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -426,9 +426,9 @@ definitions:
|
||||
type: object
|
||||
requests.Move:
|
||||
properties:
|
||||
new:
|
||||
source:
|
||||
type: string
|
||||
old:
|
||||
target:
|
||||
type: string
|
||||
type: object
|
||||
requests.NetworkConnectDisConnect:
|
||||
@@ -2051,6 +2051,12 @@ paths:
|
||||
- in: query
|
||||
name: path
|
||||
type: string
|
||||
- in: query
|
||||
name: limit
|
||||
type: integer
|
||||
- in: query
|
||||
name: page
|
||||
type: integer
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
||||
@@ -3,21 +3,19 @@ module panel
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/docker/docker v25.0.5+incompatible
|
||||
github.com/docker/docker v26.1.3+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/gertd/go-pluralize v0.2.1
|
||||
github.com/go-resty/resty/v2 v2.13.1
|
||||
github.com/gookit/color v1.5.4
|
||||
github.com/gookit/validate v1.5.2
|
||||
github.com/goravel/framework v1.13.1-0.20240215091018-1a9f352e523c
|
||||
github.com/goravel/gin v1.1.6-0.20240215075927-ab614bfae9f3
|
||||
github.com/goravel/framework v1.13.1-0.20240430025652-cf76911d0286
|
||||
github.com/goravel/gin v1.1.6-0.20240426085159-718e4d6d5f4f
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/iancoleman/strcase v0.3.0
|
||||
github.com/imroc/req/v3 v3.43.1
|
||||
github.com/libdns/alidns v1.0.3
|
||||
github.com/libdns/cloudflare v0.1.1
|
||||
github.com/libdns/dnspod v0.0.3
|
||||
github.com/libdns/libdns v0.2.2
|
||||
github.com/mholt/acmez v1.2.0
|
||||
github.com/mholt/acmez/v2 v2.0.1
|
||||
github.com/mholt/archiver/v3 v3.5.1
|
||||
github.com/mojocn/base64Captcha v1.3.6
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
@@ -26,16 +24,17 @@ require (
|
||||
github.com/swaggo/http-swagger/v2 v2.0.2
|
||||
github.com/swaggo/swag v1.16.3
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/net v0.25.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.111.0 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go v0.112.0 // indirect
|
||||
cloud.google.com/go/compute v1.24.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.5 // indirect
|
||||
cloud.google.com/go/pubsub v1.33.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.6 // indirect
|
||||
cloud.google.com/go/pubsub v1.36.1 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.2 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
@@ -46,17 +45,17 @@ require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae // indirect
|
||||
github.com/RichardKnop/machinery/v2 v2.0.12-0.20231012204029-bdb94a90ca41 // indirect
|
||||
github.com/RichardKnop/machinery/v2 v2.0.13 // indirect
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.49.6 // indirect
|
||||
github.com/bytedance/sonic v1.11.0 // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/distribution/reference v0.5.0 // indirect
|
||||
@@ -69,7 +68,7 @@ require (
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.9.1 // indirect
|
||||
github.com/glebarez/go-sqlite v1.22.0 // indirect
|
||||
github.com/glebarez/sqlite v1.10.0 // indirect
|
||||
github.com/glebarez/sqlite v1.11.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
@@ -81,19 +80,18 @@ require (
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.15.5 // indirect
|
||||
github.com/go-redsync/redsync/v4 v4.8.1 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // 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.2.0 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.17.0 // indirect
|
||||
github.com/golang-module/carbon/v2 v2.3.8 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.17.1 // indirect
|
||||
github.com/golang-module/carbon/v2 v2.3.12 // 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
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
||||
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect
|
||||
@@ -120,7 +118,7 @@ require (
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kelseyhightower/envconfig v1.4.0 // indirect
|
||||
github.com/klauspost/compress v1.17.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
@@ -129,12 +127,12 @@ require (
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/microsoft/go-mssqldb v1.6.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/montanaflynn/stats v0.7.0 // indirect
|
||||
github.com/nrdcg/dnspod-go v0.4.0 // indirect
|
||||
github.com/nwaples/rardecode v1.1.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.16.0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
@@ -143,15 +141,13 @@ require (
|
||||
github.com/pierrec/lz4/v4 v4.1.16 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/quic-go v0.41.0 // indirect
|
||||
github.com/redis/go-redis/v9 v9.4.0 // indirect
|
||||
github.com/refraction-networking/utls v1.6.3 // indirect
|
||||
github.com/rabbitmq/amqp091-go v1.9.0 // indirect
|
||||
github.com/redis/go-redis/v9 v9.5.1 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/rotisserie/eris v0.5.4 // indirect
|
||||
github.com/rs/cors v1.10.1 // indirect
|
||||
github.com/rs/cors v1.11.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
@@ -161,7 +157,6 @@ require (
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/streadway/amqp v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/swaggo/files/v2 v2.0.0 // indirect
|
||||
@@ -172,50 +167,50 @@ require (
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/unrolled/secure v1.14.0 // indirect
|
||||
github.com/urfave/cli/v2 v2.27.1 // indirect
|
||||
github.com/urfave/cli/v2 v2.27.2 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.mongodb.org/mongo-driver v1.11.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
|
||||
go.opentelemetry.io/otel v1.22.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.22.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.22.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.7.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/oauth2 v0.16.0 // indirect
|
||||
golang.org/x/oauth2 v0.17.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
google.golang.org/api v0.153.0 // indirect
|
||||
google.golang.org/api v0.162.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
|
||||
google.golang.org/grpc v1.61.1 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/grpc v1.63.2 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/mysql v1.5.4 // indirect
|
||||
gorm.io/driver/postgres v1.5.6 // indirect
|
||||
gorm.io/driver/mysql v1.5.6 // indirect
|
||||
gorm.io/driver/postgres v1.5.7 // indirect
|
||||
gorm.io/driver/sqlserver v1.5.3 // indirect
|
||||
gorm.io/gorm v1.25.7 // indirect
|
||||
gorm.io/plugin/dbresolver v1.5.0 // indirect
|
||||
gorm.io/gorm v1.25.10 // indirect
|
||||
gorm.io/plugin/dbresolver v1.5.1 // indirect
|
||||
gotest.tools/v3 v3.5.0 // indirect
|
||||
modernc.org/libc v1.37.6 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
|
||||
@@ -16,37 +16,39 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM=
|
||||
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
|
||||
cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM=
|
||||
cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
|
||||
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
|
||||
cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
|
||||
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||
cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM=
|
||||
cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI=
|
||||
cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
|
||||
cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
|
||||
cloud.google.com/go/kms v1.15.7 h1:7caV9K3yIxvlQPAcaFffhlT7d1qpxjB1wHBtjWa13SM=
|
||||
cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/pubsub v1.10.0/go.mod h1:eNpTrkOy7dCpkNyaSNetMa6udbgecJMd0ZsTJS/cuNo=
|
||||
cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g=
|
||||
cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc=
|
||||
cloud.google.com/go/pubsub v1.36.1 h1:dfEPuGCHGbWUhaMCTHUFjfroILEkx55iUmKBZTP5f+Y=
|
||||
cloud.google.com/go/pubsub v1.36.1/go.mod h1:iYjCa9EzWOoBiTdd4ps7QoMtMln5NwaZQpK1hbRfBDE=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
|
||||
@@ -92,8 +94,8 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae h1:DcFpTQBYQ9Ct2d6sC7ol0/ynxc2pO1cpGUM+f4t5adg=
|
||||
github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae/go.mod h1:rJJ84PyA/Wlmw1hO+xTzV2wsSUon6J5ktg0g8BF2PuU=
|
||||
github.com/RichardKnop/machinery/v2 v2.0.12-0.20231012204029-bdb94a90ca41 h1:7fLtRodG39Hn6AKqKE+ejO0Jj9B8O9RQOto13lkoDac=
|
||||
github.com/RichardKnop/machinery/v2 v2.0.12-0.20231012204029-bdb94a90ca41/go.mod h1:92dLVxckr2Lv7oKxoS3Uci0Of8Cuy+lmPi2dd6Euwkw=
|
||||
github.com/RichardKnop/machinery/v2 v2.0.13 h1:uo9htg+qNBi7UeUK3jcTBl3vTO/vvLKGaOdCOKePl50=
|
||||
github.com/RichardKnop/machinery/v2 v2.0.13/go.mod h1:Yc2X/QRm9rRfAjB+93NGR+kSUqtnqqs8kME4L+TKKiw=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
@@ -114,10 +116,10 @@ github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATs
|
||||
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.11.0 h1:FwNNv6Vu4z2Onf1++LNzxB/QhitD8wuTdpZzMTGITWo=
|
||||
github.com/bytedance/sonic v1.11.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
@@ -126,19 +128,14 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
||||
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
|
||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
@@ -146,25 +143,27 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
|
||||
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dhui/dktest v0.4.0 h1:z05UmuXZHO/bgj/ds2bGMBu8FI4WA+Ag/m3ghL+om7M=
|
||||
github.com/dhui/dktest v0.4.0/go.mod h1:v/Dbz1LgCBOi2Uki2nUqLBGa83hWBGFMu5MrgMDCc78=
|
||||
github.com/dhui/dktest v0.4.1 h1:/w+IWuDXVymg3IrRJCHHOkMK10m9aNVMOyD0X12YVTg=
|
||||
github.com/dhui/dktest v0.4.1/go.mod h1:DdOqcUpL7vgyP4GlF3X3w7HbSlz8cEQzwewPveYEQbA=
|
||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE=
|
||||
github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v26.1.3+incompatible h1:lLCzRbrVZrljpVNobJu1J2FHk8V0s4BawoZippkc+xo=
|
||||
github.com/docker/docker v26.1.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
@@ -181,6 +180,8 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
@@ -191,8 +192,6 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlLgiA=
|
||||
github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
@@ -200,8 +199,8 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
||||
github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc=
|
||||
github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -242,15 +241,15 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-redsync/redsync/v4 v4.8.1 h1:rq2RvdTI0obznMdxKUWGdmmulo7lS9yCzb8fgDKOlbM=
|
||||
github.com/go-redsync/redsync/v4 v4.8.1/go.mod h1:LmUAsQuQxhzZAoGY7JS6+dNhNmZyonMZiiEDY9plotM=
|
||||
github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
|
||||
github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
||||
@@ -284,12 +283,12 @@ github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w
|
||||
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/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-migrate/migrate/v4 v4.17.0 h1:rd40H3QXU0AA4IoLllFcEAEo9dYKRHYND2gB4p7xcaU=
|
||||
github.com/golang-migrate/migrate/v4 v4.17.0/go.mod h1:+Cp2mtLP4/aXDTKb9wmXYitdrNx2HGs45rbWAo6OsKM=
|
||||
github.com/golang-module/carbon/v2 v2.3.8 h1:aowLnKwifhMqRDmzmXNtlxT7AJXZWKwaoTPcPLagAHg=
|
||||
github.com/golang-module/carbon/v2 v2.3.8/go.mod h1:XDALX7KgqmHk95xyLeaqX9/LJGbfLATyruTziq68SZ8=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4=
|
||||
github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM=
|
||||
github.com/golang-module/carbon/v2 v2.3.12 h1:VC1DwN1kBwJkh5MjXmTFryjs5g4CWyoM8HAHffZPX/k=
|
||||
github.com/golang-module/carbon/v2 v2.3.12/go.mod h1:HNsedGzXGuNciZImYP2OMnpiwq/vhIstR/vn45ib5cI=
|
||||
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=
|
||||
@@ -325,13 +324,14 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
|
||||
github.com/gomodule/redigo v1.9.2/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@@ -393,10 +393,10 @@ github.com/gookit/validate v1.5.2 h1:i5I2OQ7WYHFRPRATGu9QarR9snnNHydvwSuHXaRWAV0
|
||||
github.com/gookit/validate v1.5.2/go.mod h1:yuPy2WwDlwGRa06fFJ5XIO8QEwhRnTC2LmxmBa5SE14=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.2 h1:g68AzbePXcm0V2CpUMc9j4qVzcDn7+7aoWSjZ51C0m4=
|
||||
github.com/goravel/file-rotatelogs/v2 v2.4.2/go.mod h1:23VuSW8cBS4ax5cmbV+5AaiLpq25b8UJ96IhbAkdo8I=
|
||||
github.com/goravel/framework v1.13.1-0.20240215091018-1a9f352e523c h1:PahMfqzP8tJqagVsiWt0D41zo0vhdNRZW7VvgCdJUio=
|
||||
github.com/goravel/framework v1.13.1-0.20240215091018-1a9f352e523c/go.mod h1:5yDV4oFTZCJibqKY4C+fxMq1/rtPoLg8evYVC2uGf+M=
|
||||
github.com/goravel/gin v1.1.6-0.20240215075927-ab614bfae9f3 h1:sqXKSv1yvUZwbpv595BsE2fA4mQjTaR4x2mB7uQrzOY=
|
||||
github.com/goravel/gin v1.1.6-0.20240215075927-ab614bfae9f3/go.mod h1:D/61whQQvC6HaUNSEy7UPJokJAa6csY8k9Cw37fpEQM=
|
||||
github.com/goravel/framework v1.13.1-0.20240430025652-cf76911d0286 h1:SHlT5KRxcIOBprz8awwKv9TmXVnyIqrOf7eXMeTyj88=
|
||||
github.com/goravel/framework v1.13.1-0.20240430025652-cf76911d0286/go.mod h1:ljsNqFtfujgHw/kq5T7J//3UEhHUV02COYUVr/gr6CI=
|
||||
github.com/goravel/gin v1.1.6-0.20240426085159-718e4d6d5f4f h1:4+sGiuMXtJRgP1vDxOm5wP4z9cXr/noWDxTBU2hnvRM=
|
||||
github.com/goravel/gin v1.1.6-0.20240426085159-718e4d6d5f4f/go.mod h1:kX2QEYJO8UJRTMb52g2L+Ec/53WdJ8CHwlFeqy4fRfo=
|
||||
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/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
@@ -417,12 +417,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
|
||||
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imroc/req/v3 v3.43.1 h1:tsWAhvxik4egtHAvMlxcjaWJtHlJL8EpBqJMOm5rmyQ=
|
||||
github.com/imroc/req/v3 v3.43.1/go.mod h1:SQIz5iYop16MJxbo8ib+4LnostGCok8NQf8ToyQc2xA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
@@ -468,8 +464,8 @@ github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLA
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
@@ -509,14 +505,16 @@ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsI
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
|
||||
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
|
||||
github.com/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k=
|
||||
github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U=
|
||||
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc=
|
||||
github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -542,14 +540,10 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
|
||||
github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
|
||||
@@ -575,16 +569,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/quic-go v0.41.0 h1:aD8MmHfgqTURWNJy48IYFg2OnxwHT3JL7ahGs73lb4k=
|
||||
github.com/quic-go/quic-go v0.41.0/go.mod h1:qCkNjqczPEvgsOnxZ0eCD14lv+B2LHlFAB++CNOh9hA=
|
||||
github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo=
|
||||
github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc=
|
||||
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
|
||||
github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
|
||||
github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwyKk=
|
||||
github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/refraction-networking/utls v1.6.3 h1:MFOfRN35sSx6K5AZNIoESsBuBxS2LCgRilRIdHb6fDc=
|
||||
github.com/refraction-networking/utls v1.6.3/go.mod h1:yil9+7qSl+gBwJqztoQseO6Pr3h62pQoY1lXiNR/FPs=
|
||||
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
|
||||
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo=
|
||||
@@ -599,8 +589,8 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rotisserie/eris v0.5.4 h1:Il6IvLdAapsMhvuOahHWiBnl1G++Q0/L5UIkI5mARSk=
|
||||
github.com/rotisserie/eris v0.5.4/go.mod h1:Z/kgYTJiJtocxCbFfvRmO+QejApzG6zpyky9G1A4g9s=
|
||||
github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
|
||||
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
|
||||
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
@@ -630,8 +620,6 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
|
||||
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
||||
github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo=
|
||||
github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
@@ -679,8 +667,8 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o
|
||||
github.com/unrolled/secure v1.14.0 h1:u9vJTU/pR4Bny0ntLUMxdfLtmIRGvQf2sEFuA0TG9AE=
|
||||
github.com/unrolled/secure v1.14.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
|
||||
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
|
||||
github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
|
||||
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
|
||||
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
|
||||
@@ -693,8 +681,8 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofm
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@@ -704,6 +692,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.einride.tech/aip v0.66.0 h1:XfV+NQX6L7EOYK11yoHHFtndeaWh3KbD9/cN/6iWEt8=
|
||||
go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M=
|
||||
go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc=
|
||||
go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y=
|
||||
go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
@@ -715,6 +705,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
|
||||
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
|
||||
@@ -729,8 +721,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1
|
||||
go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg=
|
||||
go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY=
|
||||
go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
|
||||
go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0=
|
||||
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
|
||||
@@ -741,10 +733,9 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
@@ -771,8 +762,9 @@ 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.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
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=
|
||||
@@ -862,8 +854,9 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -873,8 +866,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
|
||||
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
|
||||
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
|
||||
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -950,8 +943,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -960,8 +954,9 @@ 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.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
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=
|
||||
@@ -976,8 +971,9 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1068,8 +1064,8 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.39.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4=
|
||||
google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
|
||||
google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps=
|
||||
google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1117,12 +1113,12 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg=
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 h1:rcS6EyEaoCO52hQDupoSfrxI3R6C2Tq741is7X8OvnM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917/go.mod h1:CmlNWB9lSezaYELKS5Ym1r44VrrbPUa7JTvw+6MbpJ0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -1142,8 +1138,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY=
|
||||
google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
||||
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
|
||||
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -1182,19 +1178,20 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/mysql v1.5.4 h1:igQmHfKcbaTVyAIHNhhB888vvxh8EdQ2uSUT0LPcBso=
|
||||
gorm.io/driver/mysql v1.5.4/go.mod h1:9rYxJph/u9SWkWc9yY4XJ1F/+xO0S/ChOmbk3+Z5Tvs=
|
||||
gorm.io/driver/postgres v1.5.6 h1:ydr9xEd5YAM0vxVDY0X139dyzNz10spDiDlC7+ibLeU=
|
||||
gorm.io/driver/postgres v1.5.6/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
|
||||
gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
|
||||
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/driver/sqlserver v1.5.3 h1:rjupPS4PVw+rjJkfvr8jn2lJ8BMhT4UW5FwuJY0P3Z0=
|
||||
gorm.io/driver/sqlserver v1.5.3/go.mod h1:B+CZ0/7oFJ6tAlefsKoyxdgDCXJKSgwS2bMOQZT0I00=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/plugin/dbresolver v1.5.0 h1:XVHLxh775eP0CqVh3vcfJtYqja3uFl5Wr3cKlY8jgDY=
|
||||
gorm.io/plugin/dbresolver v1.5.0/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
|
||||
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
|
||||
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/plugin/dbresolver v1.5.1 h1:s9Dj9f7r+1rE3nx/Ywzc85nXptUEaeOO0pt27xdopM8=
|
||||
gorm.io/plugin/dbresolver v1.5.1/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
|
||||
gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
|
||||
gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
+21
-9
@@ -19,7 +19,7 @@ var PluginMySQL57 = PanelPlugin{
|
||||
Slug: "mysql57",
|
||||
Version: "5.7.44",
|
||||
Requires: []string{},
|
||||
Excludes: []string{"mysql80"},
|
||||
Excludes: []string{"mysql80", "mysql84"},
|
||||
Install: `bash /www/panel/scripts/mysql/install.sh 57`,
|
||||
Uninstall: `bash /www/panel/scripts/mysql/uninstall.sh 57`,
|
||||
Update: `bash /www/panel/scripts/mysql/update.sh 57`,
|
||||
@@ -29,19 +29,31 @@ var PluginMySQL80 = PanelPlugin{
|
||||
Name: "MySQL-8.0",
|
||||
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(建议内存 > 2G 安装)",
|
||||
Slug: "mysql80",
|
||||
Version: "8.0.36",
|
||||
Version: "8.0.37",
|
||||
Requires: []string{},
|
||||
Excludes: []string{"mysql57"},
|
||||
Excludes: []string{"mysql57", "mysql84"},
|
||||
Install: `bash /www/panel/scripts/mysql/install.sh 80`,
|
||||
Uninstall: `bash /www/panel/scripts/mysql/uninstall.sh 80`,
|
||||
Update: `bash /www/panel/scripts/mysql/update.sh 80`,
|
||||
}
|
||||
|
||||
var PluginMySQL84 = PanelPlugin{
|
||||
Name: "MySQL-8.4",
|
||||
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品。(建议内存 > 2G 安装)",
|
||||
Slug: "mysql84",
|
||||
Version: "8.4.0",
|
||||
Requires: []string{},
|
||||
Excludes: []string{"mysql57", "mysql80"},
|
||||
Install: `bash /www/panel/scripts/mysql/install.sh 84`,
|
||||
Uninstall: `bash /www/panel/scripts/mysql/uninstall.sh 84`,
|
||||
Update: `bash /www/panel/scripts/mysql/update.sh 84`,
|
||||
}
|
||||
|
||||
var PluginPostgreSQL15 = PanelPlugin{
|
||||
Name: "PostgreSQL-15",
|
||||
Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。",
|
||||
Slug: "postgresql15",
|
||||
Version: "15.6",
|
||||
Version: "15.7",
|
||||
Requires: []string{},
|
||||
Excludes: []string{"postgresql16"},
|
||||
Install: `bash /www/panel/scripts/postgresql/install.sh 15`,
|
||||
@@ -53,7 +65,7 @@ var PluginPostgreSQL16 = PanelPlugin{
|
||||
Name: "PostgreSQL-16",
|
||||
Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行。",
|
||||
Slug: "postgresql16",
|
||||
Version: "16.2",
|
||||
Version: "16.3",
|
||||
Requires: []string{},
|
||||
Excludes: []string{"postgresql15"},
|
||||
Install: `bash /www/panel/scripts/postgresql/install.sh 16`,
|
||||
@@ -89,7 +101,7 @@ var PluginPHP81 = PanelPlugin{
|
||||
Name: "PHP-8.1",
|
||||
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。",
|
||||
Slug: "php81",
|
||||
Version: "8.1.27",
|
||||
Version: "8.1.28",
|
||||
Requires: []string{},
|
||||
Excludes: []string{},
|
||||
Install: `bash /www/panel/scripts/php/install.sh 81`,
|
||||
@@ -101,7 +113,7 @@ var PluginPHP82 = PanelPlugin{
|
||||
Name: "PHP-8.2",
|
||||
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。",
|
||||
Slug: "php82",
|
||||
Version: "8.2.16",
|
||||
Version: "8.2.19",
|
||||
Requires: []string{},
|
||||
Excludes: []string{},
|
||||
Install: `bash /www/panel/scripts/php/install.sh 82`,
|
||||
@@ -113,7 +125,7 @@ var PluginPHP83 = PanelPlugin{
|
||||
Name: "PHP-8.3",
|
||||
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言。",
|
||||
Slug: "php83",
|
||||
Version: "8.3.3",
|
||||
Version: "8.3.7",
|
||||
Requires: []string{},
|
||||
Excludes: []string{},
|
||||
Install: `bash /www/panel/scripts/php/install.sh 83`,
|
||||
@@ -197,7 +209,7 @@ var PluginFail2ban = PanelPlugin{
|
||||
Name: "Fail2ban",
|
||||
Description: "Fail2ban 扫描系统日志文件并从中找出多次尝试失败的IP地址,将该IP地址加入防火墙的拒绝访问列表中。",
|
||||
Slug: "fail2ban",
|
||||
Version: "1.0.0",
|
||||
Version: "1.0.2",
|
||||
Requires: []string{},
|
||||
Excludes: []string{},
|
||||
Install: `bash /www/panel/scripts/fail2ban/install.sh`,
|
||||
|
||||
@@ -185,13 +185,8 @@ func (s *CertImpl) CertStore(request requests.CertStore) error {
|
||||
cert.Domains = request.Domains
|
||||
cert.AutoRenew = request.AutoRenew
|
||||
cert.UserID = request.UserID
|
||||
|
||||
if request.DNSID != nil {
|
||||
cert.DNSID = request.DNSID
|
||||
}
|
||||
if request.WebsiteID != nil {
|
||||
cert.WebsiteID = request.WebsiteID
|
||||
}
|
||||
cert.DNSID = request.DNSID
|
||||
cert.WebsiteID = request.WebsiteID
|
||||
|
||||
return facades.Orm().Query().Create(&cert)
|
||||
}
|
||||
@@ -208,13 +203,8 @@ func (s *CertImpl) CertUpdate(request requests.CertUpdate) error {
|
||||
cert.Domains = request.Domains
|
||||
cert.AutoRenew = request.AutoRenew
|
||||
cert.UserID = request.UserID
|
||||
|
||||
if request.DNSID != nil {
|
||||
cert.DNSID = request.DNSID
|
||||
}
|
||||
if request.WebsiteID != nil {
|
||||
cert.WebsiteID = request.WebsiteID
|
||||
}
|
||||
cert.DNSID = request.DNSID
|
||||
cert.WebsiteID = request.WebsiteID
|
||||
|
||||
return facades.Orm().Query().Save(&cert)
|
||||
}
|
||||
@@ -391,9 +381,6 @@ func (s *CertImpl) Renew(ID uint) (acme.Certificate, error) {
|
||||
client.UseHTTP(cert.Website.Path)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return acme.Certificate{}, err
|
||||
}
|
||||
|
||||
ssl, err := client.RenewSSL(context.Background(), *cert.CertURL, cert.Domains, acme.KeyType(cert.Type))
|
||||
if err != nil {
|
||||
|
||||
@@ -245,14 +245,14 @@ func (r *Container) NetworkPrune() error {
|
||||
|
||||
// ImageList 列出镜像
|
||||
func (r *Container) ImageList() ([]image.Summary, error) {
|
||||
return r.client.ImageList(context.Background(), types.ImageListOptions{
|
||||
return r.client.ImageList(context.Background(), image.ListOptions{
|
||||
All: true,
|
||||
})
|
||||
}
|
||||
|
||||
// ImageExist 判断镜像是否存在
|
||||
func (r *Container) ImageExist(id string) (bool, error) {
|
||||
var options types.ImageListOptions
|
||||
var options image.ListOptions
|
||||
options.Filters = filters.NewArgs(filters.Arg("reference", id))
|
||||
images, err := r.client.ImageList(context.Background(), options)
|
||||
if err != nil {
|
||||
@@ -264,7 +264,7 @@ func (r *Container) ImageExist(id string) (bool, error) {
|
||||
|
||||
// ImagePull 拉取镜像
|
||||
func (r *Container) ImagePull(config requests.ImagePull) error {
|
||||
options := types.ImagePullOptions{}
|
||||
options := image.PullOptions{}
|
||||
if config.Auth {
|
||||
authConfig := registry.AuthConfig{
|
||||
Username: config.Username,
|
||||
@@ -290,7 +290,7 @@ func (r *Container) ImagePull(config requests.ImagePull) error {
|
||||
|
||||
// ImageRemove 删除镜像
|
||||
func (r *Container) ImageRemove(id string) error {
|
||||
_, err := r.client.ImageRemove(context.Background(), id, types.ImageRemoveOptions{
|
||||
_, err := r.client.ImageRemove(context.Background(), id, image.RemoveOptions{
|
||||
Force: true,
|
||||
PruneChildren: true,
|
||||
})
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/goravel/framework/facades"
|
||||
"github.com/imroc/req/v3"
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"panel/app/models"
|
||||
@@ -73,9 +73,9 @@ func (r *PHPImpl) SaveFPMConfig(config string) error {
|
||||
}
|
||||
|
||||
func (r *PHPImpl) Load() ([]types.NV, error) {
|
||||
client := req.C().SetTimeout(10 * time.Second)
|
||||
client := resty.New().SetTimeout(10 * time.Second)
|
||||
resp, err := client.R().Get("http://127.0.0.1/phpfpm_status/" + r.version)
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
if err != nil || !resp.IsSuccess() {
|
||||
return nil, errors.New("获取 PHP-" + r.version + " 运行状态失败")
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ func (r *PluginImpl) All() []internal.PanelPlugin {
|
||||
internal.PluginOpenResty,
|
||||
internal.PluginMySQL57,
|
||||
internal.PluginMySQL80,
|
||||
internal.PluginMySQL84,
|
||||
internal.PluginPostgreSQL15,
|
||||
internal.PluginPostgreSQL16,
|
||||
internal.PluginPHP74,
|
||||
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
{
|
||||
"auth": {
|
||||
"token": {
|
||||
"expired": "login has expired",
|
||||
"missing": "not logged in"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"panel:cert-renew": {
|
||||
"description": "[Panel] Certificate renewal"
|
||||
},
|
||||
"panel:monitoring": {
|
||||
"description": "[Panel] System Monitoring",
|
||||
"fail": "[Panel] System monitoring failed to save"
|
||||
},
|
||||
"panel": {
|
||||
"description": "[Panel] Command line",
|
||||
"forDeveloper": "Please use the following commands under the guidance of the developer",
|
||||
"use": "Please use the following commands",
|
||||
"tool": "command line tool",
|
||||
"portFail": "failed to get panel port",
|
||||
"port": "Panel port",
|
||||
"entrance": "Panel entrance",
|
||||
"update": {
|
||||
"description": "update/fix panel to latest version",
|
||||
"taskCheck": "There is currently a task being executed and updates are prohibited.",
|
||||
"versionFail": "failed to get latest version",
|
||||
"fail": "update failed",
|
||||
"success": "update completed"
|
||||
},
|
||||
"getInfo": {
|
||||
"description": "reinitialize panel account information",
|
||||
"adminGetFail": "failed to get administrator information",
|
||||
"adminSaveFail": "failed to save administrator information",
|
||||
"passwordGenerationFail": "failed to generate password",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"address": "Panel address"
|
||||
},
|
||||
"getPort": {
|
||||
"description": "get the panel access port"
|
||||
},
|
||||
"getEntrance": {
|
||||
"description": "get panel access"
|
||||
},
|
||||
"deleteEntrance": {
|
||||
"description": "delete panel access",
|
||||
"fail": "failed to delete panel entrance",
|
||||
"success": "panel entrance deleted successfully"
|
||||
},
|
||||
"cleanTask": {
|
||||
"description": "clean up running and waiting tasks in the panel [used when tasks are stuck]",
|
||||
"fail": "failed to clean up tasks",
|
||||
"success": "tasks cleaned up successfully"
|
||||
},
|
||||
"backup": {
|
||||
"description": "back up website/MySQL database/PostgreSQL database to the specified directory and retain the specified amount",
|
||||
"paramFail": "backup type, path, name and keep amount are required",
|
||||
"start": "start backup",
|
||||
"backupDirFail": "failed to create backup directory",
|
||||
"targetSite": "target website",
|
||||
"siteNotExist": "website does not exist",
|
||||
"backupFail": "backup failed",
|
||||
"backupSuccess": "backup successful",
|
||||
"mysqlBackupFail": "MySQL database backup failed",
|
||||
"targetMysql": "target MySQL database",
|
||||
"startExport": "start exporting",
|
||||
"exportFail": "export failed",
|
||||
"exportSuccess": "export successful",
|
||||
"startCompress": "start compressing",
|
||||
"compressFail": "compression failed",
|
||||
"compressSuccess": "compression successful",
|
||||
"startMove": "start moving",
|
||||
"moveFail": "move failed",
|
||||
"moveSuccess": "move successful",
|
||||
"databaseGetFail": "failed to get database",
|
||||
"databaseNotExist": "database does not exist",
|
||||
"targetPostgres": "target PostgreSQL database",
|
||||
"cleanBackup" : "clean backup",
|
||||
"cleanupFail": "cleanup failed",
|
||||
"cleanupSuccess": "cleanup successful",
|
||||
"deleteFail": "failed to delete",
|
||||
"success": "backup completed"
|
||||
},
|
||||
"cutoff": {
|
||||
"description": "cut website logs and keep specified amount",
|
||||
"paramFail": "website domain name and keep amount are required",
|
||||
"start": "start cutting",
|
||||
"targetSite": "target website",
|
||||
"siteNotExist": "website does not exist",
|
||||
"logNotExist": "log file does not exist",
|
||||
"backupFail": "backup failed",
|
||||
"clearFail": "clearing failed",
|
||||
"cleanupFail": "cleanup failed",
|
||||
"clearLog": "clear log",
|
||||
"cutSuccess": "cutting successful",
|
||||
"cleanupSuccess": "cleanup successful",
|
||||
"end": "cutting completed"
|
||||
},
|
||||
"installPlugin": {
|
||||
"description": "install plugin",
|
||||
"paramFail": "plugin slug is required",
|
||||
"success": "task has been submitted"
|
||||
},
|
||||
"uninstallPlugin": {
|
||||
"description": "uninstall plugin",
|
||||
"paramFail": "plugin slug is required",
|
||||
"success": "task has been submitted"
|
||||
},
|
||||
"updatePlugin": {
|
||||
"description": "update plugin",
|
||||
"paramFail": "plugin slug is required",
|
||||
"success": "task has been submitted"
|
||||
},
|
||||
"addSite": {
|
||||
"description": "add website [domain name and port separated by commas]",
|
||||
"paramFail": "name, domain, port and path are required",
|
||||
"siteExist": "website already exists",
|
||||
"success": "website added successfully"
|
||||
},
|
||||
"removeSite": {
|
||||
"description": "remove website",
|
||||
"paramFail": "name is required",
|
||||
"siteNotExist": "website does not exist",
|
||||
"success": "website deleted successfully"
|
||||
},
|
||||
"init": {
|
||||
"description": "initialize the panel",
|
||||
"exist": "panel has been initialized",
|
||||
"success": "initialization successful",
|
||||
"adminFound": "failed to create administrator",
|
||||
"fail": "initialization failed"
|
||||
},
|
||||
"writePlugin": {
|
||||
"description": "write plugin installation status",
|
||||
"paramFail": "plugin slug and version are required",
|
||||
"fail": "failed to write plugin installation status",
|
||||
"success": "plugin installation status written successfully"
|
||||
},
|
||||
"deletePlugin": {
|
||||
"description": "delete plugin installation status",
|
||||
"paramFail": "plugin slug is required",
|
||||
"fail": "failed to remove plugin installation status",
|
||||
"success": "plugin installation status removed successfully"
|
||||
},
|
||||
"writeMysqlPassword": {
|
||||
"description": "write MySQL root password",
|
||||
"paramFail": "MySQL root password is required",
|
||||
"fail": "failed to write MySQL root password",
|
||||
"success": "MySQL root password written successfully"
|
||||
},
|
||||
"writeSite": {
|
||||
"description": "write website data to the panel",
|
||||
"paramFail": "name and path are required",
|
||||
"siteExist": "website already exists",
|
||||
"pathNotExist": "website directory does not exist",
|
||||
"fail": "failed to write to website",
|
||||
"success": "writing to website successfully"
|
||||
},
|
||||
"deleteSite": {
|
||||
"description": "delete panel website data",
|
||||
"paramFail": "website name is required",
|
||||
"fail": "failed to delete website",
|
||||
"success": "website deleted successfully"
|
||||
},
|
||||
"getSetting": {
|
||||
"description": "get panel setting data",
|
||||
"paramFail": "key is required"
|
||||
},
|
||||
"writeSetting": {
|
||||
"description": "write/update panel setting data",
|
||||
"paramFail": "key and value are required",
|
||||
"fail": "Writing settings failed",
|
||||
"success": "settings written successfully"
|
||||
},
|
||||
"deleteSetting": {
|
||||
"description": "delete panel setting data",
|
||||
"paramFail": "key is required",
|
||||
"fail": "failed to delete settings",
|
||||
"success": "settings deleted successfully"
|
||||
}
|
||||
},
|
||||
"panel:task": {
|
||||
"description": "[Panel] Daily tasks"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"internal": "internal system error",
|
||||
"plugin": {
|
||||
"notExist": "plugin does not exist",
|
||||
"notInstalled": "plugin :slug is not installed",
|
||||
"dependent": "plugin :slug requires dependency :dependency",
|
||||
"incompatible": "plugin :slug is incompatible with :exclude plugin"
|
||||
}
|
||||
},
|
||||
"messages": {
|
||||
"mistake": "mistake"
|
||||
},
|
||||
"status": {
|
||||
"upgrade": "Panel is currently undergoing an upgrade. Please try again later.",
|
||||
"maintain": "Panel is currently undergoing maintenance. Please try again later.",
|
||||
"closed": "Panel is closed.",
|
||||
"failed": "Panel encountered an error during operation. Please check the troubleshooting or contact support."
|
||||
}
|
||||
}
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
{
|
||||
"auth": {
|
||||
"token": {
|
||||
"expired": "登录已过期",
|
||||
"missing": "未登录"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"panel:cert-renew": {
|
||||
"description": "[面板] 证书续签"
|
||||
},
|
||||
"panel:monitoring": {
|
||||
"description": "[面板] 系统监控",
|
||||
"fail": "[面板] 系统监控保存失败"
|
||||
},
|
||||
"panel": {
|
||||
"description": "[面板] 命令行",
|
||||
"forDeveloper": "以下命令请在开发者指导下使用",
|
||||
"use": "请使用以下命令",
|
||||
"tool": "命令行工具",
|
||||
"port": "面板端口",
|
||||
"portFail": "获取面板端口失败",
|
||||
"entrance": "面板入口",
|
||||
"update": {
|
||||
"description": "更新 / 修复面板到最新版本",
|
||||
"taskCheck": "当前有任务正在执行,禁止更新",
|
||||
"versionFail": "获取最新版本失败",
|
||||
"fail": "更新失败",
|
||||
"success": "更新成功"
|
||||
},
|
||||
"getInfo": {
|
||||
"description": "重新初始化面板账号信息",
|
||||
"adminGetFail": "获取管理员信息失败",
|
||||
"adminSaveFail": "保存管理员信息失败",
|
||||
"passwordGenerationFail": "生成密码失败",
|
||||
"username": "用户名",
|
||||
"password": "密码",
|
||||
"address": "面板地址"
|
||||
},
|
||||
"getPort": {
|
||||
"description": "获取面板访问端口"
|
||||
},
|
||||
"getEntrance": {
|
||||
"description": "获取面板访问入口"
|
||||
},
|
||||
"deleteEntrance": {
|
||||
"description": "删除面板访问入口",
|
||||
"fail": "删除面板入口失败",
|
||||
"success": "删除面板入口成功"
|
||||
},
|
||||
"cleanTask": {
|
||||
"description": "清理面板运行中和等待中的任务[任务卡住时使用]",
|
||||
"fail": "清理任务失败",
|
||||
"success": "清理任务成功"
|
||||
},
|
||||
"backup": {
|
||||
"description": "备份网站 / MySQL数据库 / PostgreSQL数据库到指定目录并保留指定数量",
|
||||
"paramFail": "参数错误",
|
||||
"start": "开始备份",
|
||||
"backupDirFail": "创建备份目录失败",
|
||||
"targetSite": "目标网站",
|
||||
"siteNotExist": "网站不存在",
|
||||
"backupFail": "备份失败",
|
||||
"backupSuccess": "备份成功",
|
||||
"mysqlBackupFail": "备份MySQL数据库失败",
|
||||
"targetMysql": "目标MySQL数据库",
|
||||
"startExport": "开始导出",
|
||||
"exportFail": "导出失败",
|
||||
"exportSuccess": "导出成功",
|
||||
"startCompress": "开始压缩",
|
||||
"compressFail": "压缩失败",
|
||||
"compressSuccess": "压缩成功",
|
||||
"startMove": "开始移动",
|
||||
"moveFail": "移动失败",
|
||||
"moveSuccess": "移动成功",
|
||||
"databaseGetFail": "获取数据库失败",
|
||||
"databaseNotExist": "数据库不存在",
|
||||
"targetPostgres": "目标PostgreSQL数据库",
|
||||
"cleanBackup": "清理备份",
|
||||
"cleanupFail": "清理失败",
|
||||
"cleanupSuccess": "清理完成",
|
||||
"deleteFail": "删除失败",
|
||||
"success": "备份完成"
|
||||
},
|
||||
"cutoff": {
|
||||
"description": "切割网站日志并保留指定数量",
|
||||
"paramFail": "参数错误",
|
||||
"start": "开始切割",
|
||||
"targetSite": "目标网站",
|
||||
"siteNotExist": "网站不存在",
|
||||
"logNotExist": "日志文件不存在",
|
||||
"backupFail": "备份失败",
|
||||
"clearFail": "清空失败",
|
||||
"cleanupFail": "清理失败",
|
||||
"clearLog": "清理日志",
|
||||
"cutSuccess": "切割成功",
|
||||
"cleanupSuccess": "清理完成",
|
||||
"end": "切割完成"
|
||||
},
|
||||
"installPlugin": {
|
||||
"description": "安装插件",
|
||||
"paramFail": "参数错误",
|
||||
"success": "任务已提交"
|
||||
},
|
||||
"uninstallPlugin": {
|
||||
"description": "卸载插件",
|
||||
"paramFail": "参数错误",
|
||||
"success": "任务已提交"
|
||||
},
|
||||
"updatePlugin": {
|
||||
"description": "更新插件",
|
||||
"paramFail": "参数错误",
|
||||
"success": "任务已提交"
|
||||
},
|
||||
"addSite": {
|
||||
"description": "添加网站[域名和端口用英文逗号分隔]",
|
||||
"paramFail": "参数错误",
|
||||
"siteExist": "网站名已存在",
|
||||
"success": "网站添加成功"
|
||||
},
|
||||
"removeSite": {
|
||||
"description": "删除网站",
|
||||
"paramFail": "参数错误",
|
||||
"siteNotExist": "网站名不存在",
|
||||
"success": "网站删除成功"
|
||||
},
|
||||
"init": {
|
||||
"description": "初始化面板",
|
||||
"exist": "面板已初始化",
|
||||
"success": "初始化成功",
|
||||
"adminFail": "创建管理员失败",
|
||||
"fail": "初始化失败"
|
||||
},
|
||||
"writePlugin": {
|
||||
"description": "写入插件安装状态",
|
||||
"paramFail": "参数错误",
|
||||
"fail": "写入插件安装状态失败",
|
||||
"success": "写入插件安装状态成功"
|
||||
},
|
||||
"deletePlugin": {
|
||||
"description": "移除插件安装状态",
|
||||
"paramFail": "参数错误",
|
||||
"fail": "移除插件安装状态失败",
|
||||
"success": "移除插件安装状态成功"
|
||||
},
|
||||
"writeMysqlPassword": {
|
||||
"description": "写入MySQL root密码",
|
||||
"paramFail": "参数错误",
|
||||
"fail": "写入MySQL root密码失败",
|
||||
"success": "写入MySQL root密码成功"
|
||||
},
|
||||
"writeSite": {
|
||||
"description": "写入网站数据到面板",
|
||||
"paramFail": "参数错误",
|
||||
"siteExist": "网站已存在",
|
||||
"pathNotExist": "网站目录不存在",
|
||||
"fail": "写入网站失败",
|
||||
"success": "写入网站成功"
|
||||
},
|
||||
"deleteSite": {
|
||||
"description": "删除面板网站数据",
|
||||
"paramFail": "参数错误",
|
||||
"fail": "删除网站失败",
|
||||
"success": "删除网站成功"
|
||||
},
|
||||
"getSetting": {
|
||||
"description": "获取面板设置数据",
|
||||
"paramFail": "参数错误"
|
||||
},
|
||||
"writeSetting": {
|
||||
"description": "写入 / 更新面板设置数据",
|
||||
"paramFail": "参数错误",
|
||||
"fail": "写入设置失败",
|
||||
"success": "写入设置成功"
|
||||
},
|
||||
"deleteSetting": {
|
||||
"description": "删除面板设置数据",
|
||||
"paramFail": "参数错误",
|
||||
"fail": "删除设置失败",
|
||||
"success": "删除设置成功"
|
||||
}
|
||||
},
|
||||
"panel:task": {
|
||||
"description": "[面板] 每日任务"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"internal": "系统内部错误",
|
||||
"plugin": {
|
||||
"notExist": "插件不存在",
|
||||
"notInstalled": "插件 :slug 未安装",
|
||||
"dependent": "插件 :slug 需要依赖 :dependency 插件",
|
||||
"incompatible": "插件 :slug 不兼容 :exclude 插件"
|
||||
}
|
||||
},
|
||||
"messages": {
|
||||
"mistake": "错误"
|
||||
},
|
||||
"status": {
|
||||
"upgrade": "面板升级中,请稍后",
|
||||
"maintain": "面板正在运行维护,请稍后",
|
||||
"closed": "面板已关闭",
|
||||
"failed": "面板运行出错,请检查排除或联系支持"
|
||||
}
|
||||
}
|
||||
@@ -4,5 +4,6 @@ APP_DEBUG=false
|
||||
APP_PORT=8888
|
||||
APP_ENTRANCE=/
|
||||
APP_SSL=false
|
||||
APP_LOCALE=zh_CN
|
||||
|
||||
JWT_SECRET=
|
||||
|
||||
+2
-2
@@ -15,8 +15,8 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/mholt/acmez"
|
||||
"github.com/mholt/acmez/acme"
|
||||
"github.com/mholt/acmez/v2"
|
||||
"github.com/mholt/acmez/v2/acme"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
||||
+3
-3
@@ -5,8 +5,8 @@ import (
|
||||
"sort"
|
||||
|
||||
"github.com/libdns/libdns"
|
||||
"github.com/mholt/acmez"
|
||||
"github.com/mholt/acmez/acme"
|
||||
"github.com/mholt/acmez/v2"
|
||||
"github.com/mholt/acmez/v2/acme"
|
||||
)
|
||||
|
||||
type Certificate struct {
|
||||
@@ -66,7 +66,7 @@ func (c *Client) ObtainSSL(ctx context.Context, domains []string, keyType KeyTyp
|
||||
return Certificate{}, err
|
||||
}
|
||||
|
||||
certs, err := c.zClient.ObtainCertificate(ctx, c.Account, certPrivateKey, domains)
|
||||
certs, err := c.zClient.ObtainCertificateForSANs(ctx, c.Account, certPrivateKey, domains)
|
||||
if err != nil {
|
||||
return Certificate{}, err
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/libdns/cloudflare"
|
||||
"github.com/libdns/dnspod"
|
||||
"github.com/libdns/libdns"
|
||||
"github.com/mholt/acmez/acme"
|
||||
"github.com/mholt/acmez/v2/acme"
|
||||
"golang.org/x/net/publicsuffix"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// Package str 字符串辅助方法
|
||||
package str
|
||||
|
||||
import (
|
||||
"github.com/gertd/go-pluralize"
|
||||
"github.com/iancoleman/strcase"
|
||||
)
|
||||
|
||||
// Plural 转为复数 user -> users
|
||||
func Plural(word string) string {
|
||||
return pluralize.NewClient().Plural(word)
|
||||
}
|
||||
|
||||
// Singular 转为单数 users -> user
|
||||
func Singular(word string) string {
|
||||
return pluralize.NewClient().Singular(word)
|
||||
}
|
||||
|
||||
// Snake 转为 snake_case,如 TopicComment -> topic_comment
|
||||
func Snake(s string) string {
|
||||
return strcase.ToSnake(s)
|
||||
}
|
||||
|
||||
// Camel 转为 CamelCase,如 topic_comment -> TopicComment
|
||||
func Camel(s string) string {
|
||||
return strcase.ToCamel(s)
|
||||
}
|
||||
|
||||
// LowerCamel 转为 lowerCamelCase,如 TopicComment -> topicComment
|
||||
func LowerCamel(s string) string {
|
||||
return strcase.ToLowerCamel(s)
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package str
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type StrTestSuite struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func TestStrTestSuite(t *testing.T) {
|
||||
suite.Run(t, &StrTestSuite{})
|
||||
}
|
||||
|
||||
func (s *StrTestSuite) TestPlural() {
|
||||
s.Equal("users", Plural("user"))
|
||||
s.Equal("users", Plural("users"))
|
||||
}
|
||||
|
||||
func (s *StrTestSuite) TestSingular() {
|
||||
s.Equal("user", Singular("users"))
|
||||
s.Equal("user", Singular("user"))
|
||||
}
|
||||
|
||||
func (s *StrTestSuite) TestSnake() {
|
||||
s.Equal("topic_comment", Snake("TopicComment"))
|
||||
s.Equal("topic_comment", Snake("topic_comment"))
|
||||
}
|
||||
|
||||
func (s *StrTestSuite) TestCamel() {
|
||||
s.Equal("TopicComment", Camel("topic_comment"))
|
||||
s.Equal("TopicComment", Camel("TopicComment"))
|
||||
}
|
||||
|
||||
func (s *StrTestSuite) TestLowerCamel() {
|
||||
s.Equal("topicComment", LowerCamel("topic_comment"))
|
||||
s.Equal("topicComment", LowerCamel("TopicComment"))
|
||||
}
|
||||
+46
-1
@@ -7,12 +7,14 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/goravel/framework/support"
|
||||
"github.com/goravel/framework/support/env"
|
||||
"github.com/mholt/archiver/v3"
|
||||
"github.com/spf13/cast"
|
||||
)
|
||||
|
||||
// Write 写入文件
|
||||
@@ -111,7 +113,12 @@ func Mkdir(path string, permission os.FileMode) error {
|
||||
|
||||
// Chmod 修改文件/目录权限
|
||||
func Chmod(path string, permission os.FileMode) error {
|
||||
return os.Chmod(path, permission)
|
||||
if env.IsWindows() {
|
||||
return errors.New("chmod is not supported on Windows")
|
||||
}
|
||||
|
||||
cmd := exec.Command("chmod", "-R", permission.String(), path)
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// Chown 修改文件或目录所有者
|
||||
@@ -258,3 +265,41 @@ func TempDir(prefix string) (string, error) {
|
||||
func TempFile(prefix string) (*os.File, error) {
|
||||
return os.CreateTemp("", prefix)
|
||||
}
|
||||
|
||||
// IsSymlink 判读是否为软链接
|
||||
func IsSymlink(mode os.FileMode) bool {
|
||||
return mode&os.ModeSymlink != 0
|
||||
}
|
||||
|
||||
// IsHidden 判断是否为隐藏文件
|
||||
func IsHidden(path string) bool {
|
||||
_, file := filepath.Split(path)
|
||||
return strings.HasPrefix(file, ".")
|
||||
}
|
||||
|
||||
// GetSymlink 获取软链接目标
|
||||
func GetSymlink(path string) string {
|
||||
linkPath, err := os.Readlink(path)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return linkPath
|
||||
}
|
||||
|
||||
// GetUser 通过 uid 获取用户名
|
||||
func GetUser(uid uint32) string {
|
||||
usr, err := user.LookupId(cast.ToString(uid))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return usr.Username
|
||||
}
|
||||
|
||||
// GetGroup 通过 gid 获取组名
|
||||
func GetGroup(gid uint32) string {
|
||||
usr, err := user.LookupGroupId(cast.ToString(gid))
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return usr.Name
|
||||
}
|
||||
|
||||
@@ -175,8 +175,8 @@ func (s *SystemHelperTestSuite) TestChmod() {
|
||||
err := Write(filePath.Name(), "test data", 0644)
|
||||
s.Nil(err)
|
||||
|
||||
s.Nil(Chmod(filePath.Name(), 0755))
|
||||
s.Nil(filePath.Close())
|
||||
s.Nil(Chmod(filePath.Name(), 0755))
|
||||
s.Nil(Remove(filePath.Name()))
|
||||
}
|
||||
|
||||
|
||||
+7
-12
@@ -9,10 +9,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/gookit/color"
|
||||
"github.com/goravel/framework/support/carbon"
|
||||
"github.com/goravel/framework/support/env"
|
||||
"github.com/imroc/req/v3"
|
||||
"github.com/shirou/gopsutil/cpu"
|
||||
"github.com/shirou/gopsutil/disk"
|
||||
"github.com/shirou/gopsutil/host"
|
||||
@@ -407,7 +407,6 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
|
||||
color.Greenln("前置检查...")
|
||||
if Exists("/tmp/panel-storage.zip") || Exists("/tmp/panel.conf.bak") {
|
||||
color.Redln("检测到 /tmp 存在临时文件,可能是上次更新失败导致的,请谨慎排除后重试")
|
||||
return errors.New("检测到 /tmp 存在临时文件,可能是上次更新失败导致的,请谨慎排除后重试")
|
||||
}
|
||||
|
||||
@@ -426,7 +425,6 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
return err
|
||||
}
|
||||
if !Exists("/tmp/panel-storage.zip") || !Exists("/tmp/panel.conf.bak") {
|
||||
color.Redln("备份面板数据失败")
|
||||
return errors.New("备份面板数据失败")
|
||||
}
|
||||
color.Greenln("备份完成")
|
||||
@@ -487,7 +485,6 @@ func UpdatePanel(panelInfo PanelInfo) error {
|
||||
return err
|
||||
}
|
||||
if !Exists("/www/panel/storage/panel.db") || !Exists("/www/panel/panel.conf") {
|
||||
color.Redln("恢复面板数据失败")
|
||||
return errors.New("恢复面板数据失败")
|
||||
}
|
||||
color.Greenln("恢复完成")
|
||||
@@ -529,13 +526,12 @@ func RestartPanel() {
|
||||
|
||||
// IsChina 是否中国大陆
|
||||
func IsChina() bool {
|
||||
client := req.C()
|
||||
client := resty.New()
|
||||
client.SetTimeout(5 * time.Second)
|
||||
client.SetCommonRetryCount(2)
|
||||
client.ImpersonateSafari()
|
||||
client.SetRetryCount(2)
|
||||
|
||||
resp, err := client.R().Get("https://www.cloudflare-cn.com/cdn-cgi/trace")
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
if err != nil || !resp.IsSuccess() {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -548,13 +544,12 @@ func IsChina() bool {
|
||||
|
||||
// GetPublicIP 获取公网IP
|
||||
func GetPublicIP() (string, error) {
|
||||
client := req.C()
|
||||
client := resty.New()
|
||||
client.SetTimeout(5 * time.Second)
|
||||
client.SetCommonRetryCount(2)
|
||||
client.ImpersonateSafari()
|
||||
client.SetRetryCount(2)
|
||||
|
||||
resp, err := client.R().Get("https://www.cloudflare-cn.com/cdn-cgi/trace")
|
||||
if err != nil || !resp.IsSuccessState() {
|
||||
if err != nil || !resp.IsSuccess() {
|
||||
return "", errors.New("获取公网IP失败")
|
||||
}
|
||||
|
||||
|
||||
+86
-56
@@ -25,64 +25,94 @@ func Plugin() {
|
||||
route.Post("clearErrorLog", openRestyController.ClearErrorLog)
|
||||
})
|
||||
r.Prefix("mysql57").Group(func(route route.Router) {
|
||||
mysql57Controller := plugins.NewMysql57Controller()
|
||||
route.Get("status", mysql57Controller.Status)
|
||||
route.Post("reload", mysql57Controller.Reload)
|
||||
route.Post("start", mysql57Controller.Start)
|
||||
route.Post("stop", mysql57Controller.Stop)
|
||||
route.Post("restart", mysql57Controller.Restart)
|
||||
route.Get("load", mysql57Controller.Load)
|
||||
route.Get("config", mysql57Controller.GetConfig)
|
||||
route.Post("config", mysql57Controller.SaveConfig)
|
||||
route.Get("errorLog", mysql57Controller.ErrorLog)
|
||||
route.Post("clearErrorLog", mysql57Controller.ClearErrorLog)
|
||||
route.Get("slowLog", mysql57Controller.SlowLog)
|
||||
route.Post("clearSlowLog", mysql57Controller.ClearSlowLog)
|
||||
route.Get("rootPassword", mysql57Controller.GetRootPassword)
|
||||
route.Post("rootPassword", mysql57Controller.SetRootPassword)
|
||||
route.Get("databases", mysql57Controller.DatabaseList)
|
||||
route.Post("databases", mysql57Controller.AddDatabase)
|
||||
route.Delete("databases", mysql57Controller.DeleteDatabase)
|
||||
route.Get("backups", mysql57Controller.BackupList)
|
||||
route.Post("backups", mysql57Controller.CreateBackup)
|
||||
route.Put("backups", mysql57Controller.UploadBackup)
|
||||
route.Delete("backups", mysql57Controller.DeleteBackup)
|
||||
route.Post("backups/restore", mysql57Controller.RestoreBackup)
|
||||
route.Get("users", mysql57Controller.UserList)
|
||||
route.Post("users", mysql57Controller.AddUser)
|
||||
route.Delete("users", mysql57Controller.DeleteUser)
|
||||
route.Post("users/password", mysql57Controller.SetUserPassword)
|
||||
route.Post("users/privileges", mysql57Controller.SetUserPrivileges)
|
||||
mySQLController := plugins.NewMySQLController()
|
||||
route.Get("status", mySQLController.Status)
|
||||
route.Post("reload", mySQLController.Reload)
|
||||
route.Post("start", mySQLController.Start)
|
||||
route.Post("stop", mySQLController.Stop)
|
||||
route.Post("restart", mySQLController.Restart)
|
||||
route.Get("load", mySQLController.Load)
|
||||
route.Get("config", mySQLController.GetConfig)
|
||||
route.Post("config", mySQLController.SaveConfig)
|
||||
route.Get("errorLog", mySQLController.ErrorLog)
|
||||
route.Post("clearErrorLog", mySQLController.ClearErrorLog)
|
||||
route.Get("slowLog", mySQLController.SlowLog)
|
||||
route.Post("clearSlowLog", mySQLController.ClearSlowLog)
|
||||
route.Get("rootPassword", mySQLController.GetRootPassword)
|
||||
route.Post("rootPassword", mySQLController.SetRootPassword)
|
||||
route.Get("databases", mySQLController.DatabaseList)
|
||||
route.Post("databases", mySQLController.AddDatabase)
|
||||
route.Delete("databases", mySQLController.DeleteDatabase)
|
||||
route.Get("backups", mySQLController.BackupList)
|
||||
route.Post("backups", mySQLController.CreateBackup)
|
||||
route.Put("backups", mySQLController.UploadBackup)
|
||||
route.Delete("backups", mySQLController.DeleteBackup)
|
||||
route.Post("backups/restore", mySQLController.RestoreBackup)
|
||||
route.Get("users", mySQLController.UserList)
|
||||
route.Post("users", mySQLController.AddUser)
|
||||
route.Delete("users", mySQLController.DeleteUser)
|
||||
route.Post("users/password", mySQLController.SetUserPassword)
|
||||
route.Post("users/privileges", mySQLController.SetUserPrivileges)
|
||||
})
|
||||
r.Prefix("mysql80").Group(func(route route.Router) {
|
||||
mysql80Controller := plugins.NewMysql80Controller()
|
||||
route.Get("status", mysql80Controller.Status)
|
||||
route.Post("reload", mysql80Controller.Reload)
|
||||
route.Post("start", mysql80Controller.Start)
|
||||
route.Post("stop", mysql80Controller.Stop)
|
||||
route.Post("restart", mysql80Controller.Restart)
|
||||
route.Get("load", mysql80Controller.Load)
|
||||
route.Get("config", mysql80Controller.GetConfig)
|
||||
route.Post("config", mysql80Controller.SaveConfig)
|
||||
route.Get("errorLog", mysql80Controller.ErrorLog)
|
||||
route.Post("clearErrorLog", mysql80Controller.ClearErrorLog)
|
||||
route.Get("slowLog", mysql80Controller.SlowLog)
|
||||
route.Post("clearSlowLog", mysql80Controller.ClearSlowLog)
|
||||
route.Get("rootPassword", mysql80Controller.GetRootPassword)
|
||||
route.Post("rootPassword", mysql80Controller.SetRootPassword)
|
||||
route.Get("databases", mysql80Controller.DatabaseList)
|
||||
route.Post("databases", mysql80Controller.AddDatabase)
|
||||
route.Delete("databases", mysql80Controller.DeleteDatabase)
|
||||
route.Get("backups", mysql80Controller.BackupList)
|
||||
route.Post("backups", mysql80Controller.CreateBackup)
|
||||
route.Put("backups", mysql80Controller.UploadBackup)
|
||||
route.Delete("backups", mysql80Controller.DeleteBackup)
|
||||
route.Post("backups/restore", mysql80Controller.RestoreBackup)
|
||||
route.Get("users", mysql80Controller.UserList)
|
||||
route.Post("users", mysql80Controller.AddUser)
|
||||
route.Delete("users", mysql80Controller.DeleteUser)
|
||||
route.Post("users/password", mysql80Controller.SetUserPassword)
|
||||
route.Post("users/privileges", mysql80Controller.SetUserPrivileges)
|
||||
mySQLController := plugins.NewMySQLController()
|
||||
route.Get("status", mySQLController.Status)
|
||||
route.Post("reload", mySQLController.Reload)
|
||||
route.Post("start", mySQLController.Start)
|
||||
route.Post("stop", mySQLController.Stop)
|
||||
route.Post("restart", mySQLController.Restart)
|
||||
route.Get("load", mySQLController.Load)
|
||||
route.Get("config", mySQLController.GetConfig)
|
||||
route.Post("config", mySQLController.SaveConfig)
|
||||
route.Get("errorLog", mySQLController.ErrorLog)
|
||||
route.Post("clearErrorLog", mySQLController.ClearErrorLog)
|
||||
route.Get("slowLog", mySQLController.SlowLog)
|
||||
route.Post("clearSlowLog", mySQLController.ClearSlowLog)
|
||||
route.Get("rootPassword", mySQLController.GetRootPassword)
|
||||
route.Post("rootPassword", mySQLController.SetRootPassword)
|
||||
route.Get("databases", mySQLController.DatabaseList)
|
||||
route.Post("databases", mySQLController.AddDatabase)
|
||||
route.Delete("databases", mySQLController.DeleteDatabase)
|
||||
route.Get("backups", mySQLController.BackupList)
|
||||
route.Post("backups", mySQLController.CreateBackup)
|
||||
route.Put("backups", mySQLController.UploadBackup)
|
||||
route.Delete("backups", mySQLController.DeleteBackup)
|
||||
route.Post("backups/restore", mySQLController.RestoreBackup)
|
||||
route.Get("users", mySQLController.UserList)
|
||||
route.Post("users", mySQLController.AddUser)
|
||||
route.Delete("users", mySQLController.DeleteUser)
|
||||
route.Post("users/password", mySQLController.SetUserPassword)
|
||||
route.Post("users/privileges", mySQLController.SetUserPrivileges)
|
||||
})
|
||||
r.Prefix("mysql84").Group(func(route route.Router) {
|
||||
mySQLController := plugins.NewMySQLController()
|
||||
route.Get("status", mySQLController.Status)
|
||||
route.Post("reload", mySQLController.Reload)
|
||||
route.Post("start", mySQLController.Start)
|
||||
route.Post("stop", mySQLController.Stop)
|
||||
route.Post("restart", mySQLController.Restart)
|
||||
route.Get("load", mySQLController.Load)
|
||||
route.Get("config", mySQLController.GetConfig)
|
||||
route.Post("config", mySQLController.SaveConfig)
|
||||
route.Get("errorLog", mySQLController.ErrorLog)
|
||||
route.Post("clearErrorLog", mySQLController.ClearErrorLog)
|
||||
route.Get("slowLog", mySQLController.SlowLog)
|
||||
route.Post("clearSlowLog", mySQLController.ClearSlowLog)
|
||||
route.Get("rootPassword", mySQLController.GetRootPassword)
|
||||
route.Post("rootPassword", mySQLController.SetRootPassword)
|
||||
route.Get("databases", mySQLController.DatabaseList)
|
||||
route.Post("databases", mySQLController.AddDatabase)
|
||||
route.Delete("databases", mySQLController.DeleteDatabase)
|
||||
route.Get("backups", mySQLController.BackupList)
|
||||
route.Post("backups", mySQLController.CreateBackup)
|
||||
route.Put("backups", mySQLController.UploadBackup)
|
||||
route.Delete("backups", mySQLController.DeleteBackup)
|
||||
route.Post("backups/restore", mySQLController.RestoreBackup)
|
||||
route.Get("users", mySQLController.UserList)
|
||||
route.Post("users", mySQLController.AddUser)
|
||||
route.Delete("users", mySQLController.DeleteUser)
|
||||
route.Post("users/password", mySQLController.SetUserPassword)
|
||||
route.Post("users/privileges", mySQLController.SetUserPrivileges)
|
||||
})
|
||||
r.Prefix("postgresql15").Group(func(route route.Router) {
|
||||
postgresql15Controller := plugins.NewPostgresql15Controller()
|
||||
|
||||
@@ -111,7 +111,7 @@ Prepare_System() {
|
||||
fi
|
||||
|
||||
# 自动开启 BBR
|
||||
isBBRSupported=$(sysctl net.ipv4.tcp_available_congestion_control | grep -c bbr)
|
||||
isBBRSupported=$(ls -l /lib/modules/*/kernel/net/ipv4/tcp_bbr.ko.xz | grep -c bbr)
|
||||
if [ "${isBBRSupported}" != "0" ]; then
|
||||
qdisc=$(sysctl net.core.default_qdisc | awk '{print $3}')
|
||||
echo "net.core.default_qdisc=${qdisc}" >> /etc/sysctl.conf
|
||||
@@ -140,21 +140,21 @@ Prepare_System() {
|
||||
sed -i 's|^metalink|#metalink|' /etc/yum.repos.d/epel*
|
||||
dnf makecache -y
|
||||
fi
|
||||
dnf config-manager --set-enabled PowerTools
|
||||
# EL 8
|
||||
dnf config-manager --set-enabled powertools
|
||||
dnf config-manager --set-enabled CRB
|
||||
dnf config-manager --set-enabled Crb
|
||||
# EL 9
|
||||
dnf config-manager --set-enabled crb
|
||||
# Rocky Linux
|
||||
/usr/bin/crb enable
|
||||
dnf makecache -y
|
||||
dnf install -y curl wget zip unzip tar git jq git-core dos2unix podman
|
||||
dnf install -y curl wget zip unzip tar p7zip p7zip-plugins git jq git-core dos2unix podman rsyslog
|
||||
elif [ "${OS}" == "debian" ]; then
|
||||
if ${inChina}; then
|
||||
sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
|
||||
sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
|
||||
fi
|
||||
apt-get update -y
|
||||
apt-get install -y curl wget zip unzip tar git jq git dos2unix podman rsyslog
|
||||
apt-get install -y curl wget zip unzip tar p7zip p7zip-full git jq git dos2unix podman rsyslog
|
||||
fi
|
||||
if [ "$?" != "0" ]; then
|
||||
echo -e $HR
|
||||
@@ -162,7 +162,9 @@ Prepare_System() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
systemctl enable rsyslog
|
||||
systemctl enable podman
|
||||
systemctl start rsyslog
|
||||
systemctl start podman
|
||||
if [ "$?" != "0" ]; then
|
||||
echo -e $HR
|
||||
@@ -273,7 +275,7 @@ Init_Panel() {
|
||||
chmod -R 700 /usr/bin/panel
|
||||
# 防火墙放行
|
||||
if [ "${OS}" == "centos" ]; then
|
||||
yum install firewalld -y
|
||||
dnf install firewalld -y
|
||||
systemctl enable firewalld
|
||||
systemctl start firewalld
|
||||
firewall-cmd --set-default-zone=public > /dev/null 2>&1
|
||||
|
||||
+23
-39
@@ -22,7 +22,7 @@ HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
memTotal=$(LC_ALL=C free -m | grep Mem | awk '{print $2}')
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/mysql"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/mysql"
|
||||
setupPath="/www"
|
||||
mysqlPath="${setupPath}/server/mysql"
|
||||
mysqlVersion=""
|
||||
@@ -31,8 +31,11 @@ cpuCore=$(cat /proc/cpuinfo | grep "processor" | wc -l)
|
||||
source ${setupPath}/panel/scripts/calculate_j.sh
|
||||
j=$(calculate_j)
|
||||
|
||||
if [[ "${1}" == "80" ]]; then
|
||||
mysqlVersion="8.0.36"
|
||||
if [[ "${1}" == "84" ]]; then
|
||||
mysqlVersion="8.4.0"
|
||||
j=$(calculate_j2)
|
||||
elif [[ "${1}" == "80" ]]; then
|
||||
mysqlVersion="8.0.37"
|
||||
j=$(calculate_j2)
|
||||
elif [[ "${1}" == "57" ]]; then
|
||||
mysqlVersion="5.7.44"
|
||||
@@ -69,53 +72,34 @@ mkdir -p ${mysqlPath}
|
||||
cd ${mysqlPath}
|
||||
|
||||
# 下载源码
|
||||
wget -T 120 -t 3 -O ${mysqlPath}/mysql-boost-${mysqlVersion}.tar.gz ${downloadUrl}/mysql-boost-${mysqlVersion}.tar.gz
|
||||
wget -T 20 -t 3 -O ${mysqlPath}/mysql-boost-${mysqlVersion}.tar.gz.checksum.txt ${downloadUrl}/mysql-boost-${mysqlVersion}.tar.gz.checksum.txt
|
||||
|
||||
# 校验
|
||||
if ! sha256sum --status -c mysql-boost-${mysqlVersion}.tar.gz.checksum.txt; then
|
||||
wget -T 120 -t 3 -O ${mysqlPath}/mysql-${mysqlVersion}.7z ${downloadUrl}/mysql-${mysqlVersion}.7z
|
||||
wget -T 20 -t 3 -O ${mysqlPath}/mysql-${mysqlVersion}.7z.checksum.txt ${downloadUrl}/mysql-${mysqlVersion}.7z.checksum.txt
|
||||
if ! sha256sum --status -c mysql-${mysqlVersion}.7z.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:MySQL 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
rm -rf ${mysqlPath}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf mysql-boost-${mysqlVersion}.tar.gz
|
||||
rm -f mysql-boost-${mysqlVersion}.tar.gz
|
||||
rm -f mysql-boost-${mysqlVersion}.tar.gz.checksum.txt
|
||||
mv mysql-${mysqlVersion} src
|
||||
|
||||
# openssl
|
||||
wget -T 120 -t 3 -O ${mysqlPath}/openssl-1.1.1w.tar.gz ${downloadUrl}/openssl/openssl-1.1.1w.tar.gz
|
||||
wget -T 20 -t 3 -O ${mysqlPath}/openssl-1.1.1w.tar.gz.checksum.txt ${downloadUrl}/openssl/openssl-1.1.1w.tar.gz.checksum.txt
|
||||
|
||||
# 校验
|
||||
if ! sha256sum --status -c openssl-1.1.1w.tar.gz.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:OpenSSL 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
rm -rf ${mysqlPath}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf openssl-1.1.1w.tar.gz
|
||||
rm -f openssl-1.1.1w.tar.gz
|
||||
rm -f openssl-1.1.1w.tar.gz.checksum.txt
|
||||
mv openssl-1.1.1w openssl
|
||||
cd openssl
|
||||
./config --prefix=/usr/local/openssl-1.1 --openssldir=/usr/local/openssl-1.1 no-tests
|
||||
make -j$(nproc)
|
||||
make install
|
||||
echo "/usr/local/openssl-1.1/lib" > /etc/ld.so.conf.d/openssl-1.1.conf
|
||||
ldconfig
|
||||
cd ..
|
||||
rm -rf openssl
|
||||
7z x mysql-${mysqlVersion}.7z
|
||||
rm -f mysql-${mysqlVersion}.7z
|
||||
rm -f mysql-${mysqlVersion}.7z.checksum.txt
|
||||
|
||||
# 编译
|
||||
mv mysql-${mysqlVersion} src
|
||||
chmod -R 755 src
|
||||
cd src
|
||||
rm mysql-test/CMakeLists.txt
|
||||
sed -i 's/ADD_SUBDIRECTORY(mysql-test)//g' CMakeLists.txt
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=${mysqlPath} -DMYSQL_DATADIR=${mysqlPath}/data -DSYSCONFDIR=${mysqlPath}/conf -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_general_ci -DENABLED_LOCAL_INFILE=1 -DWITH_DEBUG=0 -DWITH_UNIT_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DWITH_SYSTEMD=1 -DSYSTEMD_PID_DIR=${mysqlPath} -DWITH_SSL=/usr/local/openssl-1.1 -DWITH_BOOST=../boost
|
||||
# 5.7 需要 boost
|
||||
if [[ "${1}" == "57" ]]; then
|
||||
MAYBE_WITH_BOOST="-DWITH_BOOST=../boost"
|
||||
fi
|
||||
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=${mysqlPath} -DMYSQL_DATADIR=${mysqlPath}/data -DSYSCONFDIR=${mysqlPath}/conf -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_general_ci -DENABLED_LOCAL_INFILE=1 -DWITH_DEBUG=0 -DWITH_UNIT_TESTS=OFF -DINSTALL_MYSQLTESTDIR= -DCMAKE_BUILD_TYPE=Release -DWITH_SYSTEMD=1 -DSYSTEMD_PID_DIR=${mysqlPath} ${MAYBE_WITH_BOOST}
|
||||
if [ "$?" != "0" ]; then
|
||||
echo -e $HR
|
||||
echo "错误:MySQL 编译初始化失败,请截图错误信息寻求帮助。"
|
||||
@@ -210,7 +194,7 @@ EOF
|
||||
sed -i 's/innodb_write_io_threads = 4/innodb_write_io_threads = '${cpuCore}'/g' ${mysqlPath}/conf/my.cnf
|
||||
sed -i 's/innodb_read_io_threads = 4/innodb_read_io_threads = '${cpuCore}'/g' ${mysqlPath}/conf/my.cnf
|
||||
|
||||
if [[ "${1}" == "80" ]]; then
|
||||
if [[ "${1}" == "84" ]] || [[ "${1}" == "80" ]]; then
|
||||
sed -i '/query_cache_size/d' ${mysqlPath}/conf/my.cnf
|
||||
fi
|
||||
if [[ "${1}" == "57" ]]; then
|
||||
|
||||
+24
-37
@@ -22,7 +22,7 @@ HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
memTotal=$(LC_ALL=C free -m | grep Mem | awk '{print $2}')
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/mysql"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/mysql"
|
||||
setupPath="/www"
|
||||
mysqlPath="${setupPath}/server/mysql"
|
||||
mysqlVersion=""
|
||||
@@ -32,8 +32,11 @@ cpuCore=$(cat /proc/cpuinfo | grep "processor" | wc -l)
|
||||
source ${setupPath}/panel/scripts/calculate_j.sh
|
||||
j=$(calculate_j)
|
||||
|
||||
if [[ "${1}" == "80" ]]; then
|
||||
mysqlVersion="8.0.36"
|
||||
if [[ "${1}" == "84" ]]; then
|
||||
mysqlVersion="8.4.0"
|
||||
j=$(calculate_j2)
|
||||
elif [[ "${1}" == "80" ]]; then
|
||||
mysqlVersion="8.0.37"
|
||||
j=$(calculate_j2)
|
||||
elif [[ "${1}" == "57" ]]; then
|
||||
mysqlVersion="5.7.44"
|
||||
@@ -47,11 +50,11 @@ fi
|
||||
if [ "${OS}" == "centos" ]; then
|
||||
dnf makecache -y
|
||||
dnf groupinstall "Development Tools" -y
|
||||
dnf install cmake bison ncurses-devel libtirpc-devel openssl-devel pkg-config openldap-devel libudev-devel cyrus-sasl-devel patchelf rpcgen rpcsvc-proto-devel -y
|
||||
dnf install cmake bison ncurses-devel libtirpc-devel openssl-devel pkg-config openldap-devel libudev-devel cyrus-sasl-devel patchelf rpcgen rpcsvc-proto-devel p7zip p7zip-plugins -y
|
||||
dnf install gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils gcc-toolset-12-annobin-annocheck gcc-toolset-12-annobin-plugin-gcc -y
|
||||
elif [ "${OS}" == "debian" ]; then
|
||||
apt-get update
|
||||
apt-get install build-essential cmake bison libncurses5-dev libtirpc-dev libssl-dev pkg-config libldap2-dev libudev-dev libsasl2-dev patchelf -y
|
||||
apt-get install build-essential cmake bison libncurses5-dev libtirpc-dev libssl-dev pkg-config libldap2-dev libudev-dev libsasl2-dev patchelf p7zip p7zip-full -y
|
||||
else
|
||||
echo -e $HR
|
||||
echo "错误:耗子 Linux 面板不支持该系统"
|
||||
@@ -65,48 +68,32 @@ systemctl stop mysqld
|
||||
cd ${mysqlPath}
|
||||
|
||||
# 下载源码
|
||||
wget -T 120 -t 3 -O ${mysqlPath}/mysql-boost-${mysqlVersion}.tar.gz ${downloadUrl}/mysql-boost-${mysqlVersion}.tar.gz
|
||||
wget -T 20 -t 3 -O ${mysqlPath}/mysql-boost-${mysqlVersion}.tar.gz.checksum.txt ${downloadUrl}/mysql-boost-${mysqlVersion}.tar.gz.checksum.txt
|
||||
|
||||
if ! sha256sum --status -c mysql-boost-${mysqlVersion}.tar.gz.checksum.txt; then
|
||||
wget -T 120 -t 3 -O ${mysqlPath}/mysql-${mysqlVersion}.7z ${downloadUrl}/mysql-${mysqlVersion}.7z
|
||||
wget -T 20 -t 3 -O ${mysqlPath}/mysql-${mysqlVersion}.7z.checksum.txt ${downloadUrl}/mysql-${mysqlVersion}.7z.checksum.txt
|
||||
if ! sha256sum --status -c mysql-${mysqlVersion}.7z.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:MySQL 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
rm -rf ${mysqlPath}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf mysql-boost-${mysqlVersion}.tar.gz
|
||||
rm -f mysql-boost-${mysqlVersion}.tar.gz
|
||||
rm -f mysql-boost-${mysqlVersion}.tar.gz.checksum.txt
|
||||
mv mysql-${mysqlVersion} src
|
||||
|
||||
# openssl
|
||||
wget -T 120 -t 3 -O ${mysqlPath}/openssl-1.1.1w.tar.gz ${downloadUrl}/openssl/openssl-1.1.1w.tar.gz
|
||||
wget -T 20 -t 3 -O ${mysqlPath}/openssl-1.1.1w.tar.gz.checksum.txt ${downloadUrl}/openssl/openssl-1.1.1w.tar.gz.checksum.txt
|
||||
|
||||
if ! sha256sum --status -c openssl-1.1.1w.tar.gz.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:OpenSSL 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf openssl-1.1.1w.tar.gz
|
||||
rm -f openssl-1.1.1w.tar.gz
|
||||
rm -f openssl-1.1.1w.tar.gz.checksum.txt
|
||||
mv openssl-1.1.1w openssl
|
||||
cd openssl
|
||||
./config --prefix=/usr/local/openssl-1.1 --openssldir=/usr/local/openssl-1.1 no-tests
|
||||
make "-j${j}"
|
||||
make install
|
||||
echo "/usr/local/openssl-1.1/lib" > /etc/ld.so.conf.d/openssl-1.1.conf
|
||||
ldconfig
|
||||
cd ..
|
||||
rm -rf openssl
|
||||
7z x mysql-${mysqlVersion}.7z
|
||||
rm -f mysql-${mysqlVersion}.7z
|
||||
rm -f mysql-${mysqlVersion}.7z.checksum.txt
|
||||
|
||||
# 编译
|
||||
mv mysql-${mysqlVersion} src
|
||||
chmod -R 755 src
|
||||
cd src
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=${mysqlPath} -DMYSQL_DATADIR=${mysqlPath}/data -DSYSCONFDIR=${mysqlPath}/conf -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_EXTRA_CHARSETS=all -DEXTRA_CHARSETS=all -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_general_ci -DENABLED_LOCAL_INFILE=1 -DWITH_SYSTEMD=1 -DSYSTEMD_PID_DIR=${mysqlPath} -DWITH_SSL=/usr/local/openssl-1.1 -DWITH_BOOST=../boost
|
||||
|
||||
# 5.7 需要 boost
|
||||
if [[ "${1}" == "57" ]]; then
|
||||
MAYBE_WITH_BOOST="-DWITH_BOOST=../boost"
|
||||
fi
|
||||
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=${mysqlPath} -DMYSQL_DATADIR=${mysqlPath}/data -DSYSCONFDIR=${mysqlPath}/conf -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DDEFAULT_CHARSET=utf8mb4 -DDEFAULT_COLLATION=utf8mb4_general_ci -DENABLED_LOCAL_INFILE=1 -DWITH_DEBUG=0 -DWITH_UNIT_TESTS=OFF -DINSTALL_MYSQLTESTDIR= -DCMAKE_BUILD_TYPE=Release -DWITH_SYSTEMD=1 -DSYSTEMD_PID_DIR=${mysqlPath} ${MAYBE_WITH_BOOST}
|
||||
if [ "$?" != "0" ]; then
|
||||
echo -e $HR
|
||||
echo "错误:MySQL 编译初始化失败,请截图错误信息寻求帮助。"
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/openresty"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/openresty"
|
||||
setupPath="/www"
|
||||
openrestyPath="${setupPath}/server/openresty"
|
||||
openrestyVersion="1.25.3.1"
|
||||
@@ -66,20 +66,21 @@ mv openresty-${openrestyVersion} src
|
||||
cd src
|
||||
|
||||
# openssl
|
||||
wget -T 120 -t 3 -O openssl-3.0.12.tar.gz ${downloadUrl}/openssl/openssl-3.0.12.tar.gz
|
||||
wget -T 20 -t 3 -O openssl-3.0.12.tar.gz.checksum.txt ${downloadUrl}/openssl/openssl-3.0.12.tar.gz.checksum.txt
|
||||
wget -T 120 -t 3 -O openssl-3.0.12.7z ${downloadUrl}/openssl/openssl-3.0.12.7z
|
||||
wget -T 20 -t 3 -O openssl-3.0.12.7z.checksum.txt ${downloadUrl}/openssl/openssl-3.0.12.7z.checksum.txt
|
||||
|
||||
if ! sha256sum --status -c openssl-3.0.12.tar.gz.checksum.txt; then
|
||||
if ! sha256sum --status -c openssl-3.0.12.7z.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:OpenSSL 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
rm -rf ${openrestyPath}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf openssl-3.0.12.tar.gz
|
||||
rm -f openssl-3.0.12.tar.gz
|
||||
rm -f openssl-3.0.12.tar.gz.checksum.txt
|
||||
7z x openssl-3.0.12.7z
|
||||
rm -f openssl-3.0.12.7z
|
||||
rm -f openssl-3.0.12.7z.checksum.txt
|
||||
mv openssl-3.0.12 openssl
|
||||
chmod -R 755 openssl
|
||||
|
||||
# patch openssl
|
||||
cd openssl
|
||||
@@ -99,20 +100,21 @@ rm -f openssl-3.0.12-sess_set_get_cb_yield.patch.checksum.txt
|
||||
cd ../
|
||||
|
||||
# pcre2
|
||||
wget -T 60 -t 3 -O pcre2-10.42.tar.gz ${downloadUrl}/pcre/pcre2-10.42.tar.gz
|
||||
wget -T 20 -t 3 -O pcre2-10.42.tar.gz.checksum.txt ${downloadUrl}/pcre/pcre2-10.42.tar.gz.checksum.txt
|
||||
wget -T 60 -t 3 -O pcre2-10.43.7z ${downloadUrl}/pcre/pcre2-10.43.7z
|
||||
wget -T 20 -t 3 -O pcre2-10.43.7z.checksum.txt ${downloadUrl}/pcre/pcre2-10.43.7z.checksum.txt
|
||||
|
||||
if ! sha256sum --status -c pcre2-10.42.tar.gz.checksum.txt; then
|
||||
if ! sha256sum --status -c pcre2-10.43.7z.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:pcre2 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
rm -rf ${openrestyPath}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf pcre2-10.42.tar.gz
|
||||
rm -f pcre2-10.42.tar.gz
|
||||
rm -f pcre2-10.42.tar.gz.checksum.txt
|
||||
mv pcre2-10.42 pcre2
|
||||
7z x pcre2-10.43.7z
|
||||
rm -f pcre2-10.43.7z
|
||||
rm -f pcre2-10.43.7z.checksum.txt
|
||||
mv pcre2-10.43 pcre2
|
||||
chmod -R 755 pcre2
|
||||
|
||||
# ngx_cache_purge
|
||||
wget -T 20 -t 3 -O ngx_cache_purge-2.3.tar.gz ${downloadUrl}/modules/ngx_cache_purge-2.3.tar.gz
|
||||
|
||||
+11
-10
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/php"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/php"
|
||||
setupPath="/www"
|
||||
phpVersion="${1}"
|
||||
phpVersionCode=""
|
||||
@@ -65,31 +65,32 @@ if [ "${phpVersion}" == "74" ]; then
|
||||
elif [ "${phpVersion}" == "80" ]; then
|
||||
phpVersionCode="8.0.30"
|
||||
elif [ "${phpVersion}" == "81" ]; then
|
||||
phpVersionCode="8.1.27"
|
||||
phpVersionCode="8.1.28"
|
||||
elif [ "${phpVersion}" == "82" ]; then
|
||||
phpVersionCode="8.2.16"
|
||||
phpVersionCode="8.2.19"
|
||||
elif [ "${phpVersion}" == "83" ]; then
|
||||
phpVersionCode="8.3.3"
|
||||
phpVersionCode="8.3.7"
|
||||
else
|
||||
echo -e $HR
|
||||
echo "错误:PHP-${phpVersion}不支持,请检查版本号是否正确。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
wget -T 120 -t 3 -O ${phpPath}/php-${phpVersionCode}.tar.gz ${downloadUrl}/php-${phpVersionCode}.tar.gz
|
||||
wget -T 20 -t 3 -O ${phpPath}/php-${phpVersionCode}.tar.gz.checksum.txt ${downloadUrl}/php-${phpVersionCode}.tar.gz.checksum.txt
|
||||
wget -T 120 -t 3 -O ${phpPath}/php-${phpVersionCode}.7z ${downloadUrl}/php-${phpVersionCode}.7z
|
||||
wget -T 20 -t 3 -O ${phpPath}/php-${phpVersionCode}.7z.checksum.txt ${downloadUrl}/php-${phpVersionCode}.7z.checksum.txt
|
||||
|
||||
if ! sha256sum --status -c php-${phpVersionCode}.tar.gz.checksum.txt; then
|
||||
if ! sha256sum --status -c php-${phpVersionCode}.7z.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:PHP-${phpVersion}源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
rm -rf ${phpPath}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -xvf php-${phpVersionCode}.tar.gz
|
||||
rm -f php-${phpVersionCode}.tar.gz
|
||||
rm -f php-${phpVersionCode}.tar.gz.checksum.txt
|
||||
7z x php-${phpVersionCode}.7z
|
||||
rm -f php-${phpVersionCode}.7z
|
||||
rm -f php-${phpVersionCode}.7z.checksum.txt
|
||||
mv php-* src
|
||||
chmod -R 755 src
|
||||
|
||||
if [ "${phpVersion}" -le "80" ]; then
|
||||
wget -T 120 -t 3 -O ${phpPath}/openssl-1.1.1w.tar.gz ${downloadUrl}/openssl/openssl-1.1.1w.tar.gz
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
HR="+----------------------------------------------------"
|
||||
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/php_extensions"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/php_extensions"
|
||||
action="$1"
|
||||
phpVersion="$2"
|
||||
swowVersion="1.4.1"
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
HR="+----------------------------------------------------"
|
||||
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/php_extensions"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/php_extensions"
|
||||
action="$1"
|
||||
phpVersion="$2"
|
||||
igbinaryVersion="3.2.15"
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
HR="+----------------------------------------------------"
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/php_extensions"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/php_extensions"
|
||||
action="$1"
|
||||
phpVersion="$2"
|
||||
imagickVersion="3.7.0"
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
HR="+----------------------------------------------------"
|
||||
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/php_extensions"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/php_extensions"
|
||||
action="$1"
|
||||
phpVersion="$2"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
HR="+----------------------------------------------------"
|
||||
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/php_extensions"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/php_extensions"
|
||||
action="$1"
|
||||
phpVersion="$2"
|
||||
phpredisVersion="5.3.7"
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
HR="+----------------------------------------------------"
|
||||
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/php_extensions"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/php_extensions"
|
||||
action="$1"
|
||||
phpVersion="$2"
|
||||
swooleVersion="5.1.2"
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/phpmyadmin"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/phpmyadmin"
|
||||
setupPath="/www"
|
||||
phpmyadminPath="${setupPath}/server/phpmyadmin"
|
||||
phpmyadminVersion="5.2.1"
|
||||
|
||||
@@ -22,7 +22,7 @@ HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
memTotal=$(LC_ALL=C free -m | grep Mem | awk '{print $2}')
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/postgresql"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/postgresql"
|
||||
setupPath="/www"
|
||||
postgresqlPath="${setupPath}/server/postgresql"
|
||||
postgresqlVersion=""
|
||||
@@ -31,9 +31,9 @@ source ${setupPath}/panel/scripts/calculate_j.sh
|
||||
j=$(calculate_j)
|
||||
|
||||
if [[ "${1}" == "15" ]]; then
|
||||
postgresqlVersion="15.6"
|
||||
postgresqlVersion="15.7"
|
||||
elif [[ "${1}" == "16" ]]; then
|
||||
postgresqlVersion="16.2"
|
||||
postgresqlVersion="16.3"
|
||||
else
|
||||
echo -e $HR
|
||||
echo "错误:不支持的 PostgreSQL 版本!"
|
||||
@@ -66,20 +66,21 @@ mkdir -p ${postgresqlPath}
|
||||
cd ${postgresqlPath}
|
||||
|
||||
# 下载源码
|
||||
wget -T 120 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.tar.gz ${downloadUrl}/postgresql-${postgresqlVersion}.tar.gz
|
||||
wget -T 20 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.tar.gz.checksum.txt ${downloadUrl}/postgresql-${postgresqlVersion}.tar.gz.checksum.txt
|
||||
wget -T 120 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.7z ${downloadUrl}/postgresql-${postgresqlVersion}.7z
|
||||
wget -T 20 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.7z.checksum.txt ${downloadUrl}/postgresql-${postgresqlVersion}.7z.checksum.txt
|
||||
|
||||
if ! sha256sum --status -c postgresql-${postgresqlVersion}.tar.gz.checksum.txt; then
|
||||
if ! sha256sum --status -c postgresql-${postgresqlVersion}.7z.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:PostgreSQL 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
rm -rf ${postgresqlPath}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf postgresql-${postgresqlVersion}.tar.gz
|
||||
rm -f postgresql-${postgresqlVersion}.tar.gz
|
||||
rm -f postgresql-${postgresqlVersion}.tar.gz.checksum.txt
|
||||
7z x postgresql-${postgresqlVersion}.7z
|
||||
rm -f postgresql-${postgresqlVersion}.7z
|
||||
rm -f postgresql-${postgresqlVersion}.7z.checksum.txt
|
||||
mv postgresql-${postgresqlVersion} src
|
||||
chmod -R 755 src
|
||||
|
||||
# 编译
|
||||
cd src
|
||||
|
||||
@@ -22,7 +22,7 @@ HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
memTotal=$(LC_ALL=C free -m | grep Mem | awk '{print $2}')
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/postgresql"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/postgresql"
|
||||
setupPath="/www"
|
||||
postgresqlPath="${setupPath}/server/postgresql"
|
||||
postgresqlVersion=""
|
||||
@@ -31,9 +31,9 @@ source ${setupPath}/panel/scripts/calculate_j.sh
|
||||
j=$(calculate_j)
|
||||
|
||||
if [[ "${1}" == "15" ]]; then
|
||||
postgresqlVersion="15.6"
|
||||
postgresqlVersion="15.7"
|
||||
elif [[ "${1}" == "16" ]]; then
|
||||
postgresqlVersion="16.2"
|
||||
postgresqlVersion="16.3"
|
||||
else
|
||||
echo -e $HR
|
||||
echo "错误:不支持的 PostgreSQL 版本!"
|
||||
@@ -62,19 +62,20 @@ rm -rf ${postgresqlPath}/src
|
||||
cd ${postgresqlPath}
|
||||
|
||||
# 下载源码
|
||||
wget -T 120 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.tar.gz ${downloadUrl}/postgresql-${postgresqlVersion}.tar.gz
|
||||
wget -T 20 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.tar.gz.checksum.txt ${downloadUrl}/postgresql-${postgresqlVersion}.tar.gz.checksum.txt
|
||||
wget -T 120 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.7z ${downloadUrl}/postgresql-${postgresqlVersion}.7z
|
||||
wget -T 20 -t 3 -O ${postgresqlPath}/postgresql-${postgresqlVersion}.7z.checksum.txt ${downloadUrl}/postgresql-${postgresqlVersion}.7z.checksum.txt
|
||||
|
||||
if ! sha256sum --status -c postgresql-${postgresqlVersion}.tar.gz.checksum.txt; then
|
||||
if ! sha256sum --status -c postgresql-${postgresqlVersion}.7z.checksum.txt; then
|
||||
echo -e $HR
|
||||
echo "错误:PostgreSQL 源码 checksum 校验失败,文件可能被篡改或不完整,已终止操作"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar -zxvf postgresql-${postgresqlVersion}.tar.gz
|
||||
rm -f postgresql-${postgresqlVersion}.tar.gz
|
||||
rm -f postgresql-${postgresqlVersion}.tar.gz.checksum.txt
|
||||
7z x postgresql-${postgresqlVersion}.7z
|
||||
rm -f postgresql-${postgresqlVersion}.7z
|
||||
rm -f postgresql-${postgresqlVersion}.7z.checksum.txt
|
||||
mv postgresql-${postgresqlVersion} src
|
||||
chmod -R 755 src
|
||||
|
||||
# 编译
|
||||
cd src
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
HR="+----------------------------------------------------"
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/pure-ftpd"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/pure-ftpd"
|
||||
setupPath="/www"
|
||||
pureftpdPath="${setupPath}/server/pure-ftpd"
|
||||
pureftpdVersion="1.0.50"
|
||||
|
||||
@@ -20,7 +20,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
HR="+----------------------------------------------------"
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/pure-ftpd"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/pure-ftpd"
|
||||
setupPath="/www"
|
||||
pureftpdPath="${setupPath}/server/pure-ftpd"
|
||||
pureftpdVersion="1.0.50"
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/redis"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/redis"
|
||||
setupPath="/www"
|
||||
redisPath="${setupPath}/server/redis"
|
||||
redisVersion="7.2.4"
|
||||
|
||||
@@ -21,7 +21,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
HR="+----------------------------------------------------"
|
||||
ARCH=$(uname -m)
|
||||
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
|
||||
downloadUrl="https://git.haozi.net/opensource/download/-/raw/main/panel/redis"
|
||||
downloadUrl="https://dl.cdn.haozi.net/panel/redis"
|
||||
setupPath="/www"
|
||||
redisPath="${setupPath}/server/redis"
|
||||
redisVersion="7.2.4"
|
||||
|
||||
+17
-2
@@ -90,8 +90,8 @@ if version_lt "$oldVersion" "2.1.39"; then
|
||||
echo "更新面板到 v2.1.39 ..."
|
||||
echo "Update panel to v2.1.39 ..."
|
||||
if [ "${OS}" == "centos" ]; then
|
||||
yum makecache
|
||||
yum install -y podman
|
||||
dnf makecache
|
||||
dnf install -y podman
|
||||
else
|
||||
apt-get update -y
|
||||
apt-get install -y podman
|
||||
@@ -101,6 +101,21 @@ if version_lt "$oldVersion" "2.1.39"; then
|
||||
systemctl start podman
|
||||
fi
|
||||
|
||||
if version_lt "$oldVersion" "2.2.0"; then
|
||||
echo "更新面板到 v2.2.0 ..."
|
||||
echo "Update panel to v2.2.0 ..."
|
||||
echo "APP_LOCALE=zh_CN" >> $panelPath/panel.conf
|
||||
if [ "${OS}" == "centos" ]; then
|
||||
dnf makecache
|
||||
dnf install -y p7zip p7zip-plugins rsyslog
|
||||
systemctl enable rsyslog
|
||||
systemctl start rsyslog
|
||||
else
|
||||
apt-get update -y
|
||||
apt-get install -y p7zip p7zip-full
|
||||
fi
|
||||
fi
|
||||
|
||||
echo $HR
|
||||
echo "更新结束"
|
||||
echo "Update finished"
|
||||
|
||||
Reference in New Issue
Block a user