Compare commits

...

14 Commits

Author SHA1 Message Date
耗子 ec10cd30a5 feat: 发布v2.2.8 2024-06-12 01:37:40 +08:00
耗子 847fae5caa feat: 名称统一为耗子面板 2024-06-12 01:36:35 +08:00
耗子 b3b8c22634 feat: 名称统一为耗子面板 2024-06-12 01:32:11 +08:00
耗子 5f504d49ef feat: 创建容器后自动启动 2024-06-12 01:09:09 +08:00
耗子 44045da4eb feat: 添加默认404页面 2024-06-11 03:36:11 +08:00
耗子 baf90c0602 feat: 发布v2.2.7 2024-06-11 03:19:32 +08:00
耗子 f7e67c3797 fix: chmod权限问题 2024-06-11 03:19:06 +08:00
耗子 d7a79fa53e feat: 发布v2.2.6 2024-06-11 02:07:52 +08:00
耗子 b9b3b9fedf feat: 不再默认安装podman 2024-06-11 02:03:46 +08:00
耗子 e27940a71b feat: Podman插件 2024-06-11 01:26:34 +08:00
耗子 aa22933b36 Merge remote-tracking branch 'origin/main' 2024-06-10 01:54:33 +08:00
耗子 a1dceaaa82 feat: 添加Podman安装脚本 2024-06-10 01:53:28 +08:00
机器人 ebd5d37e78 Merge branch 'renovate/github.com-gorilla-websocket-1.x' into 'main'
chore(deps): Update module github.com/gorilla/websocket to v1.5.2

See merge request opensource/panel!76
2024-06-08 16:12:13 +00:00
机器人 107d2ec658 chore(deps): Update module github.com/gorilla/websocket to v1.5.2 2024-06-08 16:06:59 +00:00
40 changed files with 1510 additions and 116 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
## 行为准则
耗子 Linux 面板遵守业界通用的行为准则。任何违反行为准则的行为都可以报告给我们:
耗子面板遵守业界通用的行为准则。任何违反行为准则的行为都可以报告给我们:
- 参与者将容忍反对意见。
- 参与者必须确保他们的语言和行为没有人身攻击和贬低个人言论。
@@ -9,7 +9,7 @@
## Code of Conduct
The HaoZi Linux Panel complies with the industry's common code of conduct. Any breach of the Code of Conduct can be reported to us:
The Rat Panel complies with the industry's common code of conduct. Any breach of the Code of Conduct can be reported to us:
- Participants will be tolerant of opposing views.
- Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
+6 -6
View File
@@ -2,7 +2,7 @@
[简体中文] | [<a href="README_EN.md">English</a>]
</p>
<h1 align="center">耗子 Linux 面板</h1>
<h1 align="center">耗子面板</h1>
<p align="center">
<a href="https://github.com/TheTNB/panel/releases"><img src="https://img.shields.io/github/release/TheTNB/panel.svg"></a>
@@ -12,7 +12,7 @@
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2FTheTNB%2Fpanel?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2FTheTNB%2Fpanel.svg?type=shield" alt="FOSSA Status"></a>
</p>
耗子 Linux 面板是使用 Golang + Vue 开发的开源轻量 Linux 服务器运维管理面板。
耗子面板是使用 Golang + Vue 开发的开源轻量 Linux 服务器运维管理面板。
交流QQ群:[12370907](https://jq.qq.com/?_wv=1027&k=I1oJKSTH) | 论坛:[tom.moe](https://tom.moe) | 赞助:[爱发电](https://afdian.net/a/TheTNB)
@@ -32,7 +32,7 @@
## 运行环境
耗子 Linux 面板仅支持 `amd64` | `arm64` 架构下的主流系统的最新版本,不支持 `Ubuntu`,因为其发版太过频繁,难以维护。
耗子面板仅支持 `amd64` | `arm64` 架构下的主流系统的最新版本,不支持 `Ubuntu`,因为其发版太过频繁,难以维护。
低配机器建议使用 `Debian`,资源占用较 `RHEL` 系更低。其他机器建议使用 `AlmaLinux` | `RockyLinux`,维护周期更长也更稳定。
@@ -50,7 +50,7 @@
## 安装面板
> **Warning**
> 安装面板前,你需要了解 LNMP 环境的基本知识,以及如何处理常见的 LNMP 环境问题,不建议 0 基础的用户安装和使用耗子 Linux 面板。
> 安装面板前,你需要了解 LNMP 环境的基本知识,以及如何处理常见的 LNMP 环境问题,不建议 0 基础的用户安装和使用耗子面板。
如果你决定继续,请以`root`用户登录服务器,执行以下命令安装面板:
@@ -88,7 +88,7 @@ panel
## 赞助商
如果耗子 Linux 面板对你有帮助,欢迎[赞助我们](https://afdian.net/a/TheTNB),感谢以下支持者/赞助商的支持:
如果耗子面板对你有帮助,欢迎[赞助我们](https://afdian.net/a/TheTNB),感谢以下支持者/赞助商的支持:
**同时接受云资源赞助,可通过QQ群咨询联系**
@@ -127,4 +127,4 @@ panel
## 免责声明
严禁使用耗子 Linux 面板从事任何非法活动,非法站点请勿向我们请求任何形式的技术支持,如果在技术支持过程中发现非法内容,我们将立即停止技术支持并留存相关证据。
严禁使用耗子面板从事任何非法活动,非法站点请勿向我们请求任何形式的技术支持,如果在技术支持过程中发现非法内容,我们将立即停止技术支持并留存相关证据。
+6 -6
View File
@@ -2,7 +2,7 @@
[<a href="README.md">简体中文</a>] | [English]
</p>
<h1 align="center">HaoZi Linux Panel</h1>
<h1 align="center">Rat Panel</h1>
<p align="center">
<a href="https://github.com/TheTNB/panel/releases"><img src="https://img.shields.io/github/release/TheTNB/panel.svg"></a>
@@ -12,7 +12,7 @@
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2FTheTNB%2Fpanel?ref=badge_shield"><img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2FTheTNB%2Fpanel.svg?type=shield" alt="FOSSA Status"></a>
</p>
The HaoZi Linux Panel is an open source lightweight Linux server operation and maintenance management panel developed using Golang and Vue.
The Rat Panel is an open source lightweight Linux server operation and maintenance management panel developed using Golang and Vue.
Communication QQ group: [12370907](https://jq.qq.com/?_wv=1027&k=I1oJKSTH) | Forum: [tom.moe](https://tom.moe) | Sponsor: [Open Collective](https://opencollective.com/tnb)
@@ -32,7 +32,7 @@ Communication QQ group: [12370907](https://jq.qq.com/?_wv=1027&k=I1oJKSTH) | For
## Operating Environment
HaoZi Linux Panel only supports the latest version of mainstream systems under the `amd64` | `arm64` architecture. It does not support `Ubuntu` because its releases are too frequent and difficult to maintain.
Rat Panel only supports the latest version of mainstream systems under the `amd64` | `arm64` architecture. It does not support `Ubuntu` because its releases are too frequent and difficult to maintain.
Recommended to use `Debian` for low-configuration machines, as its resource usage is lower than that of the `RHEL` system. For other machines, recommended to use `RockyLinux` | `AlmaLinux`, which has a longer maintenance cycle and is more stable.
@@ -50,7 +50,7 @@ As system versions are constantly updated, we may also terminate support for som
## Install Panel
> **Warning**
> Before installing the panel, you need to understand the basic knowledge of the LNMP environment and how to deal with common LNMP environment problems. It is not recommended for users with zero basic knowledge to install and use HaoZi Linux Panel.
> Before installing the panel, you need to understand the basic knowledge of the LNMP environment and how to deal with common LNMP environment problems. It is not recommended for users with zero basic knowledge to install and use Rat Panel.
If you decide to continue, please log in to the server as `root` user and execute the following command to install the panel:
@@ -88,7 +88,7 @@ For issues with the panel itself, you can submit feedback on the `Issues` page o
## Sponsor
If the HaoZi Linux Panel is helpful to you, welcome to [sponsor us](https://opencollective.com/tnb), thanks to the following supporters/sponsors:
If the Rat 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**
@@ -127,4 +127,4 @@ This project owes its existence to all those who have contributed. To contribute
## Disclaimer
It is strictly prohibited to use the HaoZi Linux Panel to engage in any illegal activities. Please do not request any form of technical support from us for illegal sites. If illegal content is discovered during the technical support process, we will immediately stop technical support and retain relevant evidence.
It is strictly prohibited to use the Rat Panel to engage in any illegal activities. Please do not request any form of technical support from us for illegal sites. If illegal content is discovered during the technical support process, we will immediately stop technical support and retain relevant evidence.
+4 -4
View File
@@ -1,8 +1,8 @@
## 安全说明
安全性是我们最关心的问题之一,我们已在多个不同应用的生产环境广泛应用耗子 Linux 面板,至今无一例安全事故。
安全性是我们最关心的问题之一,我们已在多个不同应用的生产环境广泛应用耗子面板,至今无一例安全事故。
耗子 Linux 面板采用业界多种方案尽可能保证面板的安全性,但是我们不能保证面板的绝对安全性,**因此我们不对面板的安全性做任何保证**。
耗子面板采用业界多种方案尽可能保证面板的安全性,但是我们不能保证面板的绝对安全性,**因此我们不对面板的安全性做任何保证**。
如果您在使用面板的过程中发现任何安全问题,请勿提交 Issue,可通过以下方式直接联系我们:
@@ -13,9 +13,9 @@
## Security Policy
Security is one of our biggest concerns. We have widely used HaoZi Linux Panel in production environments for many different applications, and there has been no safety incident so far.
Security is one of our biggest concerns. We have widely used Rat Panel in production environments for many different applications, and there has been no safety incident so far.
HaoZi Linux Panel adopts various solutions in the industry to ensure the security of the panel as much as possible, but we cannot guarantee the absolute security of the panel, **therefore we do not make any guarantees on the security of the panel**.
Rat Panel adopts various solutions in the industry to ensure the security of the panel as much as possible, but we cannot guarantee the absolute security of the panel, **therefore we do not make any guarantees on the security of the panel**.
If you find any security issues while using the panel, please do not submit an Issue. You can contact us directly through the following methods:
+1 -1
View File
@@ -63,7 +63,7 @@ func (receiver *Panel) Handle(ctx console.Context) error {
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")}}
settings := []models.Setting{{Key: models.SettingKeyName, Value: "耗子面板"}, {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.Red().Printfln(translate.Get("commands.panel.init.fail"))
@@ -201,6 +201,10 @@ func (r *ContainerController) ContainerCreate(ctx http.Context) http.Response {
return Error(ctx, http.StatusInternalServerError, err.Error())
}
if err = r.container.ContainerStart(id); err != nil {
return Error(ctx, http.StatusInternalServerError, err.Error())
}
return Success(ctx, id)
}
+2 -2
View File
@@ -85,7 +85,7 @@ func (r *CronController) Add(ctx http.Context) http.Response {
shell = `#!/bin/bash
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
# 耗子 Linux 面板 - 数据备份脚本
# 耗子面板 - 数据备份脚本
type=` + backupType + `
path=` + backupPath + `
@@ -102,7 +102,7 @@ panel backup ${type} ${name} ${path} ${save} 2>&1
shell = `#!/bin/bash
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
# 耗子 Linux 面板 - 日志切割脚本
# 耗子面板 - 日志切割脚本
name=` + website + `
save=` + cast.ToString(save) + `
@@ -0,0 +1,239 @@
package plugins
import (
"github.com/goravel/framework/contracts/http"
"github.com/TheTNB/panel/app/http/controllers"
requests "github.com/TheTNB/panel/app/http/requests/plugins/podman"
"github.com/TheTNB/panel/pkg/tools"
)
type PodmanController struct {
}
func NewPodmanController() *PodmanController {
return &PodmanController{}
}
// Status
//
// @Summary 服务状态
// @Description 获取 Podman 服务状态
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/status [get]
func (r *PodmanController) Status(ctx http.Context) http.Response {
status, err := tools.ServiceStatus("podman")
if err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务运行状态失败")
}
return controllers.Success(ctx, status)
}
// IsEnabled
//
// @Summary 是否启用服务
// @Description 获取是否启用 Podman 服务
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/isEnabled [get]
func (r *PodmanController) IsEnabled(ctx http.Context) http.Response {
enabled, err := tools.ServiceIsEnabled("podman")
if err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务启用状态失败")
}
return controllers.Success(ctx, enabled)
}
// Enable
//
// @Summary 启用服务
// @Description 启用 Podman 服务
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/enable [post]
func (r *PodmanController) Enable(ctx http.Context) http.Response {
if err := tools.ServiceEnable("podman"); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "启用 Podman 服务失败")
}
return controllers.Success(ctx, nil)
}
// Disable
//
// @Summary 禁用服务
// @Description 禁用 Podman 服务
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/disable [post]
func (r *PodmanController) Disable(ctx http.Context) http.Response {
if err := tools.ServiceDisable("podman"); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "禁用 Podman 服务失败")
}
return controllers.Success(ctx, nil)
}
// Restart
//
// @Summary 重启服务
// @Description 重启 Podman 服务
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/restart [post]
func (r *PodmanController) Restart(ctx http.Context) http.Response {
if err := tools.ServiceRestart("podman"); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "重启 Podman 服务失败")
}
return controllers.Success(ctx, nil)
}
// Start
//
// @Summary 启动服务
// @Description 启动 Podman 服务
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/start [post]
func (r *PodmanController) Start(ctx http.Context) http.Response {
if err := tools.ServiceStart("podman"); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "启动 Podman 服务失败")
}
status, err := tools.ServiceStatus("podman")
if err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务运行状态失败")
}
return controllers.Success(ctx, status)
}
// Stop
//
// @Summary 停止服务
// @Description 停止 Podman 服务
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/stop [post]
func (r *PodmanController) Stop(ctx http.Context) http.Response {
if err := tools.ServiceStop("podman"); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "停止 Podman 服务失败")
}
status, err := tools.ServiceStatus("podman")
if err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, "获取 Podman 服务运行状态失败")
}
return controllers.Success(ctx, !status)
}
// GetRegistryConfig
//
// @Summary 获取注册表配置
// @Description 获取 Podman 注册表配置
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/registryConfig [get]
func (r *PodmanController) GetRegistryConfig(ctx http.Context) http.Response {
config, err := tools.Read("/etc/containers/registries.conf")
if err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
}
return controllers.Success(ctx, config)
}
// UpdateRegistryConfig
//
// @Summary 更新注册表配置
// @Description 更新 Podman 注册表配置
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Param data body requests.UpdateRegistryConfig true "request"
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/registryConfig [post]
func (r *PodmanController) UpdateRegistryConfig(ctx http.Context) http.Response {
var updateRequest requests.UpdateRegistryConfig
sanitize := controllers.Sanitize(ctx, &updateRequest)
if sanitize != nil {
return sanitize
}
if err := tools.Write("/etc/containers/registries.conf", updateRequest.Config, 0644); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
}
if err := tools.ServiceRestart("podman"); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
}
return controllers.Success(ctx, nil)
}
// GetStorageConfig
//
// @Summary 获取存储配置
// @Description 获取 Podman 存储配置
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/storageConfig [get]
func (r *PodmanController) GetStorageConfig(ctx http.Context) http.Response {
config, err := tools.Read("/etc/containers/storage.conf")
if err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
}
return controllers.Success(ctx, config)
}
// UpdateStorageConfig
//
// @Summary 更新存储配置
// @Description 更新 Podman 存储配置
// @Tags 插件-Podman
// @Produce json
// @Security BearerToken
// @Param data body requests.UpdateStorageConfig true "request"
// @Success 200 {object} controllers.SuccessResponse
// @Router /plugins/podman/storageConfig [post]
func (r *PodmanController) UpdateStorageConfig(ctx http.Context) http.Response {
var updateRequest requests.UpdateStorageConfig
sanitize := controllers.Sanitize(ctx, &updateRequest)
if sanitize != nil {
return sanitize
}
if err := tools.Write("/etc/containers/storage.conf", updateRequest.Config, 0644); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
}
if err := tools.ServiceRestart("podman"); err != nil {
return controllers.Error(ctx, http.StatusInternalServerError, err.Error())
}
return controllers.Success(ctx, nil)
}
+2
View File
@@ -18,6 +18,8 @@ func MustInstall() http.Middleware {
var slug string
if strings.HasPrefix(path, "/api/panel/website") {
slug = "openresty"
} else if strings.HasPrefix(path, "/api/panel/container") {
slug = "podman"
} else {
pathArr := strings.Split(path, "/")
if len(pathArr) < 4 {
@@ -0,0 +1,32 @@
package requests
import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
)
type UpdateRegistryConfig struct {
Config string `form:"config" json:"config"`
}
func (r *UpdateRegistryConfig) Authorize(ctx http.Context) error {
return nil
}
func (r *UpdateRegistryConfig) Rules(ctx http.Context) map[string]string {
return map[string]string{
"config": "required|string",
}
}
func (r *UpdateRegistryConfig) Messages(ctx http.Context) map[string]string {
return map[string]string{}
}
func (r *UpdateRegistryConfig) Attributes(ctx http.Context) map[string]string {
return map[string]string{}
}
func (r *UpdateRegistryConfig) PrepareForValidation(ctx http.Context, data validation.Data) error {
return nil
}
@@ -0,0 +1,32 @@
package requests
import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/contracts/validation"
)
type UpdateStorageConfig struct {
Config string `form:"config" json:"config"`
}
func (r *UpdateStorageConfig) Authorize(ctx http.Context) error {
return nil
}
func (r *UpdateStorageConfig) Rules(ctx http.Context) map[string]string {
return map[string]string{
"config": "required|string",
}
}
func (r *UpdateStorageConfig) Messages(ctx http.Context) map[string]string {
return map[string]string{}
}
func (r *UpdateStorageConfig) Attributes(ctx http.Context) map[string]string {
return map[string]string{}
}
func (r *UpdateStorageConfig) PrepareForValidation(ctx http.Context, data validation.Data) error {
return nil
}
+2 -2
View File
@@ -7,8 +7,8 @@ import (
func init() {
config := facades.Config()
config.Add("panel", map[string]any{
"name": "耗子 Linux 面板",
"version": "v2.2.5",
"name": "耗子面板",
"version": "v2.2.8",
"ssl": config.Env("APP_SSL", false),
})
}
+311 -2
View File
@@ -3943,6 +3943,299 @@ const docTemplate = `{
}
}
},
"/plugins/podman/disable": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "禁用 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "禁用服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/enable": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "启用 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "启用服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/isEnabled": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取是否启用 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "是否启用服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/registryConfig": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取 Podman 注册表配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "获取注册表配置",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
},
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "更新 Podman 注册表配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "更新注册表配置",
"parameters": [
{
"description": "request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/requests.UpdateRegistryConfig"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/restart": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "重启 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "重启服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/start": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "启动 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "启动服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/status": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取 Podman 服务状态",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "服务状态",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/stop": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "停止 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "停止服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/storageConfig": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取 Podman 存储配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "获取存储配置",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
},
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "更新 Podman 存储配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "更新存储配置",
"parameters": [
{
"description": "request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/requests.UpdateStorageConfig"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/rsync/config": {
"get": {
"security": [
@@ -5081,6 +5374,22 @@ const docTemplate = `{
}
}
},
"requests.UpdateRegistryConfig": {
"type": "object",
"properties": {
"config": {
"type": "string"
}
}
},
"requests.UpdateStorageConfig": {
"type": "object",
"properties": {
"config": {
"type": "string"
}
}
},
"requests.UserStore": {
"type": "object",
"properties": {
@@ -5289,8 +5598,8 @@ var SwaggerInfo = &swag.Spec{
Host: "",
BasePath: "/api",
Schemes: []string{},
Title: "耗子 Linux 面板 API",
Description: "耗子 Linux 面板的 API 信息",
Title: "耗子面板 API",
Description: "耗子面板的 API 信息",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
+311 -2
View File
@@ -1,8 +1,8 @@
{
"swagger": "2.0",
"info": {
"description": "耗子 Linux 面板的 API 信息",
"title": "耗子 Linux 面板 API",
"description": "耗子面板的 API 信息",
"title": "耗子面板 API",
"contact": {
"name": "耗子科技",
"email": "admin@haozi.net"
@@ -3936,6 +3936,299 @@
}
}
},
"/plugins/podman/disable": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "禁用 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "禁用服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/enable": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "启用 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "启用服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/isEnabled": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取是否启用 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "是否启用服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/registryConfig": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取 Podman 注册表配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "获取注册表配置",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
},
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "更新 Podman 注册表配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "更新注册表配置",
"parameters": [
{
"description": "request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/requests.UpdateRegistryConfig"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/restart": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "重启 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "重启服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/start": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "启动 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "启动服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/status": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取 Podman 服务状态",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "服务状态",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/stop": {
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "停止 Podman 服务",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "停止服务",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/podman/storageConfig": {
"get": {
"security": [
{
"BearerToken": []
}
],
"description": "获取 Podman 存储配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "获取存储配置",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
},
"post": {
"security": [
{
"BearerToken": []
}
],
"description": "更新 Podman 存储配置",
"produces": [
"application/json"
],
"tags": [
"插件-Podman"
],
"summary": "更新存储配置",
"parameters": [
{
"description": "request",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/requests.UpdateStorageConfig"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/controllers.SuccessResponse"
}
}
}
}
},
"/plugins/rsync/config": {
"get": {
"security": [
@@ -5074,6 +5367,22 @@
}
}
},
"requests.UpdateRegistryConfig": {
"type": "object",
"properties": {
"config": {
"type": "string"
}
}
},
"requests.UpdateStorageConfig": {
"type": "object",
"properties": {
"config": {
"type": "string"
}
}
},
"requests.UserStore": {
"type": "object",
"properties": {
+189 -2
View File
@@ -533,6 +533,16 @@ definitions:
path:
type: string
type: object
requests.UpdateRegistryConfig:
properties:
config:
type: string
type: object
requests.UpdateStorageConfig:
properties:
config:
type: string
type: object
requests.UserStore:
properties:
ca:
@@ -662,10 +672,10 @@ info:
contact:
email: admin@haozi.net
name: 耗子科技
description: 耗子 Linux 面板的 API 信息
description: 耗子面板的 API 信息
license:
name: GNU Affero General Public License v3
title: 耗子 Linux 面板 API
title: 耗子面板 API
version: "2"
paths:
/panel/cert/algorithms:
@@ -3053,6 +3063,183 @@ paths:
summary: 停止服务
tags:
- 插件-Gitea
/plugins/podman/disable:
post:
description: 禁用 Podman 服务
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 禁用服务
tags:
- 插件-Podman
/plugins/podman/enable:
post:
description: 启用 Podman 服务
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 启用服务
tags:
- 插件-Podman
/plugins/podman/isEnabled:
get:
description: 获取是否启用 Podman 服务
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 是否启用服务
tags:
- 插件-Podman
/plugins/podman/registryConfig:
get:
description: 获取 Podman 注册表配置
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 获取注册表配置
tags:
- 插件-Podman
post:
description: 更新 Podman 注册表配置
parameters:
- description: request
in: body
name: data
required: true
schema:
$ref: '#/definitions/requests.UpdateRegistryConfig'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 更新注册表配置
tags:
- 插件-Podman
/plugins/podman/restart:
post:
description: 重启 Podman 服务
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 重启服务
tags:
- 插件-Podman
/plugins/podman/start:
post:
description: 启动 Podman 服务
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 启动服务
tags:
- 插件-Podman
/plugins/podman/status:
get:
description: 获取 Podman 服务状态
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 服务状态
tags:
- 插件-Podman
/plugins/podman/stop:
post:
description: 停止 Podman 服务
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 停止服务
tags:
- 插件-Podman
/plugins/podman/storageConfig:
get:
description: 获取 Podman 存储配置
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 获取存储配置
tags:
- 插件-Podman
post:
description: 更新 Podman 存储配置
parameters:
- description: request
in: body
name: data
required: true
schema:
$ref: '#/definitions/requests.UpdateStorageConfig'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/controllers.SuccessResponse'
security:
- BearerToken: []
summary: 更新存储配置
tags:
- 插件-Podman
/plugins/rsync/config:
get:
description: 获取 Rsync 配置
+1 -1
View File
@@ -9,7 +9,7 @@ require (
github.com/gookit/validate v1.5.2
github.com/goravel/framework v1.14.1-0.20240608091017-72e9e3621f24
github.com/goravel/gin v1.2.1
github.com/gorilla/websocket v1.5.1
github.com/gorilla/websocket v1.5.2
github.com/libdns/alidns v1.0.3
github.com/libdns/cloudflare v0.1.1
github.com/libdns/dnspod v0.0.3
+2 -2
View File
@@ -283,8 +283,8 @@ github.com/goravel/gin v1.2.1 h1:lnQX3NKUEaSx8x7AAJpoeVkXgi+MVQ9FXy4QywHQElo=
github.com/goravel/gin v1.2.1/go.mod h1:Qt3NJysg/eoxXL4y/swwFUcfcIT7XG+xb0rWChweZfY=
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=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/gorilla/websocket v1.5.2 h1:qoW6V1GT3aZxybsbC6oLnailWnB+qTMVwMreOso9XUw=
github.com/gorilla/websocket v1.5.2/go.mod h1:0n9H61RBAcf5/38py2MCYbxzPIY9rOkpvvMT24Rqs30=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
+1
View File
@@ -53,6 +53,7 @@ func (r *PluginImpl) All() []types.Plugin {
types.PluginRsync,
types.PluginSupervisor,
types.PluginFail2ban,
types.PluginPodman,
types.PluginFrp,
types.PluginGitea,
types.PluginToolBox,
+65 -10
View File
@@ -64,7 +64,7 @@ func (r *WebsiteImpl) Add(website types.Website) (models.Website, error) {
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>耗子 Linux 面板</title>
<title>耗子面板</title>
<style>
body {
background-color: #f9f9f9;
@@ -105,8 +105,8 @@ func (r *WebsiteImpl) Add(website types.Website) (models.Website, error) {
</head>
<body>
<div class="container">
<h1>耗子 Linux 面板</h1>
<p>这是耗子 Linux 面板的网站默认页面!</p>
<h1>耗子面板</h1>
<p>这是耗子面板的网站默认页面!</p>
<p>当您看到此页面,说明您的网站已创建成功。</p>
</div>
</body>
@@ -117,6 +117,67 @@ func (r *WebsiteImpl) Add(website types.Website) (models.Website, error) {
return models.Website{}, err
}
notFound := `<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 Not Found</title>
<style>
body {
background-color: #f9f9f9;
margin: 0;
padding: 0;
}
.container {
max-width: 800px;
margin: 2em auto;
background-color: #ffffff;
padding: 20px;
border-radius: 12px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5em;
margin-top: 0;
margin-bottom: 20px;
text-align: center;
color: #333;
border-bottom: 2px solid #ddd;
padding-bottom: 0.5em;
}
p {
color: #555;
line-height: 1.8;
text-align: center;
}
a {
text-decoration: none;
color: #007bff;
}
@media screen and (max-width: 768px) {
.container {
padding: 15px;
margin: 2em 15px;
}
h1 {
font-size: 1.8em;
}
}
</style>
</head>
<body>
<div class="container">
<h1>404 Not Found</h1>
<p>由 <a target="_blank" href="https://github.com/TheTNB/panel">耗子面板</a> 强力驱动</p>
</div>
</body>
</html>
`
if err := tools.Write(website.Path+"/404.html", notFound, 0644); err != nil {
return models.Website{}, err
}
portList := ""
domainList := ""
portUsed := make(map[uint]bool)
@@ -174,7 +235,7 @@ server
# waf标记位结束
# 错误页配置,可自行设置
#error_page 404 /404.html;
error_page 404 /404.html;
#error_page 502 /502.html;
# 伪静态规则引入,修改后将导致面板设置的伪静态规则失效
@@ -211,15 +272,9 @@ server
return models.Website{}, err
}
if err := tools.Chmod(r.setting.Get(models.SettingKeyWebsitePath), 0755); err != nil {
return models.Website{}, err
}
if err := tools.Chmod(website.Path, 0755); err != nil {
return models.Website{}, err
}
if err := tools.Chown(r.setting.Get(models.SettingKeyWebsitePath), "www", "www"); err != nil {
return models.Website{}, err
}
if err := tools.Chown(website.Path, "www", "www"); err != nil {
return models.Website{}, err
}
+2 -2
View File
@@ -22,9 +22,9 @@ import (
"github.com/TheTNB/panel/bootstrap"
)
// @title 耗子 Linux 面板 API
// @title 耗子面板 API
// @version 2
// @description 耗子 Linux 面板的 API 信息
// @description 耗子面板的 API 信息
// @contact.name 耗子科技
// @contact.email admin@haozi.net
+1 -1
View File
@@ -117,7 +117,7 @@ func Chmod(path string, permission os.FileMode) error {
return errors.New("chmod is not supported on Windows")
}
cmd := exec.Command("chmod", "-R", permission.String(), path)
cmd := exec.Command("chmod", "-R", fmt.Sprintf("%o", permission), path)
return cmd.Run()
}
+1 -1
View File
@@ -114,7 +114,7 @@ func Api() {
r.Get("pingStatus", safeController.GetPingStatus)
r.Post("pingStatus", safeController.SetPingStatus)
})
r.Prefix("container").Middleware(middleware.Jwt()).Group(func(r route.Router) {
r.Prefix("container").Middleware(middleware.Jwt(), middleware.MustInstall()).Group(func(r route.Router) {
containerController := controllers.NewContainerController()
r.Get("list", containerController.ContainerList)
r.Get("search", containerController.ContainerSearch)
+14
View File
@@ -340,6 +340,20 @@ func Plugin() {
route.Post("whiteList", fail2banController.SetWhiteList)
route.Get("whiteList", fail2banController.GetWhiteList)
})
r.Prefix("podman").Group(func(route route.Router) {
controller := plugins.NewPodmanController()
route.Get("status", controller.Status)
route.Get("isEnabled", controller.IsEnabled)
route.Post("enable", controller.Enable)
route.Post("disable", controller.Disable)
route.Post("start", controller.Start)
route.Post("stop", controller.Stop)
route.Post("restart", controller.Restart)
route.Get("registryConfig", controller.GetRegistryConfig)
route.Post("registryConfig", controller.UpdateRegistryConfig)
route.Get("storageConfig", controller.GetStorageConfig)
route.Post("storageConfig", controller.UpdateStorageConfig)
})
r.Prefix("rsync").Group(func(route route.Router) {
rsyncController := plugins.NewRsyncController()
route.Get("status", rsyncController.Status)
+82
View File
@@ -0,0 +1,82 @@
#!/bin/bash
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/www/server/bin:/www/server/sbin:$PATH
: '
Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'
HR="+----------------------------------------------------"
ARCH=$(uname -m)
downloadUrl="https://dl.cdn.haozi.net/panel/frp"
frpPath="/www/server/frp"
frpVersion="0.58.0"
if [ ! -d "${frpPath}" ]; then
mkdir -p ${frpPath}
fi
# 架构判断
if [ "${ARCH}" == "x86_64" ]; then
frpFile="frp_${frpVersion}_linux_amd64.7z"
elif [ "${ARCH}" == "aarch64" ]; then
frpFile="frp_${frpVersion}_linux_arm64.7z"
else
echo -e $HR
echo "错误:不支持的架构"
exit 1
fi
# 备份配置
if [ -f "${frpPath}/frps.toml" ]; then
cp -f ${frpPath}/frps.toml ${frpPath}/frps.toml.bak
fi
if [ -f "${frpPath}/frpc.toml" ]; then
cp -f ${frpPath}/frpc.toml ${frpPath}/frpc.toml.bak
fi
# 下载frp
cd ${frpPath}
wget -T 120 -t 3 -O ${frpPath}/${frpFile} ${downloadUrl}/${frpFile}
wget -T 20 -t 3 -O ${frpPath}/${frpFile}.checksum.txt ${downloadUrl}/${frpFile}.checksum.txt
if ! sha256sum --status -c ${frpPath}/${frpFile}.checksum.txt; then
echo -e $HR
echo "错误:frp checksum 校验失败,文件可能被篡改或不完整,已终止操作"
rm -rf ${frpPath}
exit 1
fi
# 解压frp
cd ${frpPath}
7z x ${frpFile}
chmod -R 700 ${frpPath}
rm -f ${frpFile} ${frpFile}.checksum.txt
# 还原配置
if [ -f "${frpPath}/frps.toml.bak" ]; then
cp -f ${frpPath}/frps.toml.bak ${frpPath}/frps.toml
fi
if [ -f "${frpPath}/frpc.toml.bak" ]; then
cp -f ${frpPath}/frpc.toml.bak ${frpPath}/frpc.toml
fi
systemctl restart frps
systemctl restart frpc
panel writePlugin frp ${frpVersion}
echo -e ${HR}
echo "frp 安装完成"
echo -e ${HR}
+1 -1
View File
@@ -49,7 +49,7 @@ elif [ "${OS}" == "debian" ]; then
apt-get install git git-lfs -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+9 -11
View File
@@ -18,7 +18,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'
LOGO="+----------------------------------------------------\n| 耗子 Linux 面板安装脚本\n+----------------------------------------------------\n| Copyright © 2022-"$(date +%Y)" 耗子科技 All rights reserved.\n+----------------------------------------------------"
LOGO="+----------------------------------------------------\n| 耗子面板安装脚本\n+----------------------------------------------------\n| Copyright © 2022-"$(date +%Y)" 耗子科技 All rights reserved.\n+----------------------------------------------------"
HR="+----------------------------------------------------"
setup_Path="/www"
sshPort=$(cat /etc/ssh/sshd_config | grep 'Port ' | awk '{print $2}')
@@ -35,12 +35,12 @@ Prepare_System() {
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
if [ "${OS}" == "unknown" ]; then
echo -e $HR
echo "错误:该系统不支持安装耗子 Linux 面板,请更换 Debian 12.x / RHEL 9.x 安装。"
echo "错误:该系统不支持安装耗子面板,请更换 Debian 12.x / RHEL 9.x 安装。"
exit 1
fi
if [ "${ARCH}" != "x86_64" ] && [ "${ARCH}" != "aarch64" ]; then
echo -e $HR
echo "错误:该系统架构不支持安装耗子 Linux 面板,请更换 x86_64 / aarch64 架构安装。"
echo "错误:该系统架构不支持安装耗子面板,请更换 x86_64 / aarch64 架构安装。"
exit 1
fi
@@ -55,21 +55,21 @@ Prepare_System() {
kernelVersion=$(uname -r | awk -F '.' '{print $1}')
if [ "${kernelVersion}" != "5" ] && [ "${kernelVersion}" != "6" ]; then
echo -e $HR
echo "错误:该系统内核版本太低,不支持安装耗子 Linux 面板,请更换 Debian 12 / RHEL 9.x 安装。"
echo "错误:该系统内核版本太低,不支持安装耗子面板,请更换 Debian 12 / RHEL 9.x 安装。"
exit 1
fi
is64bit=$(getconf LONG_BIT)
if [ "${is64bit}" != '64' ]; then
echo -e $HR
echo "错误:32 位系统不支持安装耗子 Linux 面板,请更换 64 位系统安装。"
echo "错误:32 位系统不支持安装耗子面板,请更换 64 位系统安装。"
exit 1
fi
isInstalled=$(systemctl status panel 2>&1 | grep "Active")
if [ "${isInstalled}" != "" ]; then
echo -e $HR
echo "错误:耗子 Linux 面板已安装,请勿重复安装。"
echo "错误:耗子面板已安装,请勿重复安装。"
exit 1
fi
@@ -150,14 +150,14 @@ Prepare_System() {
# Rocky Linux
/usr/bin/crb enable
dnf makecache -y
dnf install -y curl wget zip unzip tar p7zip p7zip-plugins git jq git-core dos2unix podman rsyslog
dnf install -y curl wget zip unzip tar p7zip p7zip-plugins git jq git-core dos2unix rsyslog
elif [ "${OS}" == "debian" ]; then
if ${inChina}; then
sed -i 's/deb.debian.org/mirrors.tencent.com/g' /etc/apt/sources.list
sed -i 's/security.debian.org/mirrors.tencent.com/g' /etc/apt/sources.list
fi
apt-get update -y
apt-get install -y curl wget zip unzip tar p7zip p7zip-full git jq git dos2unix podman rsyslog
apt-get install -y curl wget zip unzip tar p7zip p7zip-full git jq git dos2unix rsyslog
fi
if [ "$?" != "0" ]; then
echo -e $HR
@@ -166,9 +166,7 @@ Prepare_System() {
fi
systemctl enable rsyslog
systemctl enable podman
systemctl start rsyslog
systemctl start podman
if [ "$?" != "0" ]; then
echo -e $HR
echo "错误:安装面板依赖软件失败,请截图错误信息寻求帮助。"
@@ -230,7 +228,7 @@ Init_Panel() {
fi
else
echo -e $HR
echo "错误:该系统架构不支持安装耗子 Linux 面板,请更换 x86_64 / aarch64 架构安装。"
echo "错误:该系统架构不支持安装耗子面板,请更换 x86_64 / aarch64 架构安装。"
exit 1
fi
if [ "$?" != "0" ] || [ "${panelZip}" == "" ] || [ "${panelZipName}" == "" ]; then
+1 -1
View File
@@ -56,7 +56,7 @@ elif [ "${OS}" == "debian" ]; then
apt-get install build-essential cmake bison libncurses5-dev libtirpc-dev libssl-dev pkg-config libldap2-dev libudev-dev libsasl2-dev patchelf -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+1 -1
View File
@@ -57,7 +57,7 @@ elif [ "${OS}" == "debian" ]; then
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 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+8 -8
View File
@@ -39,7 +39,7 @@ elif [ "${OS}" == "debian" ]; then
apt-get install build-essential cmake tar unzip libgd3 libgd-dev git flex perl libonig-dev libsodium-dev libxml2-dev libxslt1-dev bison libyajl-dev curl libcurl4-openssl-dev libncurses5-dev libevent-dev libreadline-dev uuid-dev libbrotli-dev icu-devtools libicu-dev openssl libssl-dev -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
@@ -406,7 +406,7 @@ cat > ${openrestyPath}/html/index.html << EOF
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>未找到网站 - 耗子 Linux 面板</title>
<title>未找到网站 - 耗子面板</title>
<style>
body {
background-color: #f9f9f9;
@@ -447,8 +447,8 @@ cat > ${openrestyPath}/html/index.html << EOF
</head>
<body>
<div class="container">
<h1>耗子 Linux 面板</h1>
<p>这是耗子 Linux 面板的 OpenResty 默认页面!</p>
<h1>耗子面板</h1>
<p>这是耗子面板的 OpenResty 默认页面!</p>
<p>当您看到此页面,说明无法在服务器上找到该域名对应的站点。</p>
</div>
</body>
@@ -462,7 +462,7 @@ cat > ${openrestyPath}/html/stop.html << EOF
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网站已停止 - 耗子 Linux 面板</title>
<title>网站已停止 - 耗子面板</title>
<style>
body {
background-color: #f9f9f9;
@@ -503,7 +503,7 @@ cat > ${openrestyPath}/html/stop.html << EOF
</head>
<body>
<div class="container">
<h1>耗子 Linux 面板</h1>
<h1>耗子面板</h1>
<p>该网站已被管理员停止访问!</p>
<p>当您看到此页面,说明该网站已被服务器管理员停止对外访问。</p>
</div>
@@ -518,7 +518,7 @@ cat > ${openrestyPath}/html/block.html << EOF
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>请求被拦截 - 耗子 Linux 面板</title>
<title>请求被拦截 - 耗子面板</title>
<style>
body {
background-color: #f9f9f9;
@@ -559,7 +559,7 @@ cat > ${openrestyPath}/html/block.html << EOF
</head>
<body>
<div class="container">
<h1>耗子 Linux 面板</h1>
<h1>耗子面板</h1>
<p>本次请求判断为危险的攻击请求,已被拦截!</p>
<p>当您看到此页面,说明您的请求被WAF拦截,可能是由于您的请求中包含了危险的攻击内容,或者您的请求被误判为攻击请求。</p>
<p>如果您认为这是误判,请联系服务器管理员解决。</p>
+1 -1
View File
@@ -50,7 +50,7 @@ elif [ "${OS}" == "debian" ]; then
apt-get install build-essential autoconf libc6-dev libgdbm-dev libgd-tools libgd-dev perl libonig-dev libsodium-dev libxml2-dev libsqlite3-dev libzip-dev libbz2-dev liblzma-dev libpng-dev libjpeg-dev libwebp-dev libavif-dev libfreetype6-dev libgmp-dev libssl-dev libreadline-dev libxslt1-dev libcurl4-openssl-dev pkg-config libedit-dev zlib1g-dev libpcre3-dev cron libicu-dev libc-ares2 libc-ares-dev -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+1 -1
View File
@@ -42,7 +42,7 @@ Install() {
apt-get install imagemagick libmagickwand-dev -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/www/server/bin:/www/server/sbin:$PATH
: '
Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
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")
podmanVersion="4.0.0"
if [ "${OS}" == "centos" ]; then
dnf makecache -y
dnf install podman -y
elif [ "${OS}" == "debian" ]; then
apt-get update
apt-get install podman -y
else
echo -e $HR
echo "错误:耗子面板不支持该系统"
exit 1
fi
systemctl enable podman
systemctl start podman
panel writePlugin podman ${podmanVersion}
echo -e ${HR}
echo "podman 安装完成"
echo -e ${HR}
+40
View File
@@ -0,0 +1,40 @@
#!/bin/bash
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:$PATH
: '
Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
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")
systemctl stop podman
systemctl disable podman
if [ "${OS}" == "centos" ]; then
dnf remove podman -y
elif [ "${OS}" == "debian" ]; then
apt-get remove podman -y
else
echo -e $HR
echo "错误:耗子面板不支持该系统"
exit 1
fi
panel deletePlugin podman
echo -e $HR
echo "podman 卸载完成"
echo -e $HR
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/www/server/bin:/www/server/sbin:$PATH
: '
Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
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")
podmanVersion="4.0.0"
if [ "${OS}" == "centos" ]; then
dnf makecache -y
dnf update podman -y
elif [ "${OS}" == "debian" ]; then
apt-get update
apt-get upgrade podman -y
else
echo -e $HR
echo "错误:耗子面板不支持该系统"
exit 1
fi
systemctl restart podman
panel writePlugin podman ${podmanVersion}
echo -e ${HR}
echo "podman 安装完成"
echo -e ${HR}
+1 -1
View File
@@ -50,7 +50,7 @@ elif [ "${OS}" == "debian" ]; then
apt-get install build-essential make gettext zlib1g-dev libreadline-dev libicu-dev libxml2-dev libxslt-dev libssl-dev libsystemd-dev -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+1 -1
View File
@@ -50,7 +50,7 @@ elif [ "${OS}" == "debian" ]; then
apt-get install build-essential make gettext zlib1g-dev libreadline-dev libicu-dev libxml2-dev libxslt-dev libssl-dev libsystemd-dev -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+1 -1
View File
@@ -42,7 +42,7 @@ elif [ "${OS}" == "debian" ]; then
apt-get install build-essential libsystemd-dev libssl-dev -y
else
echo -e $HR
echo "错误:耗子 Linux 面板不支持该系统"
echo "错误:耗子面板不支持该系统"
exit 1
fi
+5 -5
View File
@@ -18,7 +18,7 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'
LOGO="+----------------------------------------------------\n| 耗子 Linux 面板卸载脚本\n+----------------------------------------------------\n| Copyright © 2022-"$(date +%Y)" 耗子科技 All rights reserved.\n+----------------------------------------------------"
LOGO="+----------------------------------------------------\n| 耗子面板卸载脚本\n+----------------------------------------------------\n| Copyright © 2022-"$(date +%Y)" 耗子科技 All rights reserved.\n+----------------------------------------------------"
HR="+----------------------------------------------------"
download_Url=""
setup_Path="/www"
@@ -33,7 +33,7 @@ Prepare_System() {
isInstalled=$(systemctl status panel 2>&1 | grep "Active")
if [ "${isInstalled}" == "" ]; then
echo -e $HR
echo "错误:耗子 Linux 面板未安装,无需卸载。"
echo "错误:耗子面板未安装,无需卸载。"
exit 1
fi
@@ -80,7 +80,7 @@ if [ "${uninstall}" != 'y' ]; then
fi
echo -e "${LOGO}"
echo '正在卸载耗子 Linux 面板...'
echo '正在卸载耗子面板...'
echo -e $HR
Prepare_System
@@ -90,8 +90,8 @@ Remove_Panel
clear
echo -e "${LOGO}"
echo '耗子 Linux 面板卸载完成。'
echo '感谢您的使用,欢迎您再次使用耗子 Linux 面板。'
echo '耗子面板卸载完成。'
echo '感谢您的使用,欢迎您再次使用耗子面板。'
echo -e $HR
rm -f uninstall_panel.sh
+9 -16
View File
@@ -22,7 +22,7 @@ HR="+----------------------------------------------------"
OS=$(source /etc/os-release && { [[ "$ID" == "debian" ]] && echo "debian"; } || { [[ "$ID" == "centos" ]] || [[ "$ID" == "rhel" ]] || [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]] && echo "centos"; } || echo "unknown")
if [ "${OS}" == "unknown" ]; then
echo -e $HR
echo "错误:该系统不支持安装耗子 Linux 面板,请更换 Debian 12.x / RHEL 9.x 安装。"
echo "错误:该系统不支持安装耗子面板,请更换 Debian 12.x / RHEL 9.x 安装。"
exit 1
fi
@@ -86,21 +86,6 @@ if version_lt "$oldVersion" "2.1.30"; then
openssl req -x509 -nodes -days 36500 -newkey ec:<(openssl ecparam -name secp384r1) -keyout $panelPath/storage/ssl.key -out $panelPath/storage/ssl.crt -subj "/C=CN/ST=Tianjin/L=Tianjin/O=HaoZi Technology Co., Ltd./OU=HaoZi Panel/CN=Panel"
fi
if version_lt "$oldVersion" "2.1.39"; then
echo "更新面板到 v2.1.39 ..."
echo "Update panel to v2.1.39 ..."
if [ "${OS}" == "centos" ]; then
dnf makecache
dnf install -y podman
else
apt-get update -y
apt-get install -y podman
fi
systemctl enable podman
systemctl start podman
fi
if version_lt "$oldVersion" "2.2.0"; then
echo "更新面板到 v2.2.0 ..."
echo "Update panel to v2.2.0 ..."
@@ -121,6 +106,14 @@ if version_lt "$oldVersion" "2.2.4"; then
fi
fi
if version_lt "$oldVersion" "2.2.6"; then
echo "更新面板到 v2.2.6 ..."
echo "Update panel to v2.2.6 ..."
if [ -f "/usr/bin/podman" ]; then
panel writePlugin podman 4.0.0
fi
fi
echo $HR
echo "更新结束"
echo "Update finished"
+34 -22
View File
@@ -2,7 +2,7 @@ package types
var PluginOpenResty = Plugin{
Name: "OpenResty",
Description: "OpenResty® 是一款基于 NGINX 和 LuaJIT 的 Web 平台",
Description: "OpenResty® 是一款基于 NGINX 和 LuaJIT 的 Web 平台",
Slug: "openresty",
Version: "1.25.3.1",
Requires: []string{},
@@ -14,7 +14,7 @@ var PluginOpenResty = Plugin{
var PluginMySQL57 = Plugin{
Name: "MySQL-5.7",
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品(已停止维护,不建议使用!预计 2025 年 12 月移除)",
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品(已停止维护,不建议使用!预计 2025 年 12 月移除)",
Slug: "mysql57",
Version: "5.7.44",
Requires: []string{},
@@ -26,7 +26,7 @@ var PluginMySQL57 = Plugin{
var PluginMySQL80 = Plugin{
Name: "MySQL-8.0",
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品(建议内存 > 2G 安装)",
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品(建议内存 > 2G 安装)",
Slug: "mysql80",
Version: "8.0.37",
Requires: []string{},
@@ -38,7 +38,7 @@ var PluginMySQL80 = Plugin{
var PluginMySQL84 = Plugin{
Name: "MySQL-8.4",
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品(建议内存 > 2G 安装)",
Description: "MySQL 是最流行的关系型数据库管理系统之一,Oracle 旗下产品(建议内存 > 2G 安装)",
Slug: "mysql84",
Version: "8.4.0",
Requires: []string{},
@@ -50,7 +50,7 @@ var PluginMySQL84 = Plugin{
var PluginPostgreSQL15 = Plugin{
Name: "PostgreSQL-15",
Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行",
Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行",
Slug: "postgresql15",
Version: "15.7",
Requires: []string{},
@@ -62,7 +62,7 @@ var PluginPostgreSQL15 = Plugin{
var PluginPostgreSQL16 = Plugin{
Name: "PostgreSQL-16",
Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行",
Description: "PostgreSQL 是世界上最先进的开源关系数据库,在类似 BSD 与 MIT 许可的 PostgreSQL 许可下发行",
Slug: "postgresql16",
Version: "16.3",
Requires: []string{},
@@ -74,7 +74,7 @@ var PluginPostgreSQL16 = Plugin{
var PluginPHP74 = Plugin{
Name: "PHP-7.4",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言(已停止维护,不建议使用!预计 2024 年 12 月移除)",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言(已停止维护,不建议使用!预计 2024 年 12 月移除)",
Slug: "php74",
Version: "7.4.33",
Requires: []string{},
@@ -86,7 +86,7 @@ var PluginPHP74 = Plugin{
var PluginPHP80 = Plugin{
Name: "PHP-8.0",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言(已停止维护,不建议使用!预计 2025 年 12 月移除)",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言(已停止维护,不建议使用!预计 2025 年 12 月移除)",
Slug: "php80",
Version: "8.0.30",
Requires: []string{},
@@ -98,7 +98,7 @@ var PluginPHP80 = Plugin{
var PluginPHP81 = Plugin{
Name: "PHP-8.1",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言",
Slug: "php81",
Version: "8.1.29",
Requires: []string{},
@@ -110,7 +110,7 @@ var PluginPHP81 = Plugin{
var PluginPHP82 = Plugin{
Name: "PHP-8.2",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言",
Slug: "php82",
Version: "8.2.20",
Requires: []string{},
@@ -122,7 +122,7 @@ var PluginPHP82 = Plugin{
var PluginPHP83 = Plugin{
Name: "PHP-8.3",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言",
Description: "PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言",
Slug: "php83",
Version: "8.3.8",
Requires: []string{},
@@ -134,7 +134,7 @@ var PluginPHP83 = Plugin{
var PluginPHPMyAdmin = Plugin{
Name: "phpMyAdmin",
Description: "phpMyAdmin 是一个以 PHP 为基础,以 Web-Base 方式架构在网站主机上的 MySQL 数据库管理工具",
Description: "phpMyAdmin 是一个以 PHP 为基础,以 Web-Base 方式架构在网站主机上的 MySQL 数据库管理工具",
Slug: "phpmyadmin",
Version: "5.2.1",
Requires: []string{},
@@ -146,7 +146,7 @@ var PluginPHPMyAdmin = Plugin{
var PluginPureFTPd = Plugin{
Name: "Pure-FTPd",
Description: "Pure-Ftpd 是一个快速、高效、轻便、安全的 FTP 服务器,它以安全和配置简单为设计目标,支持虚拟主机,IPV6,PAM 等功能",
Description: "Pure-Ftpd 是一个快速、高效、轻便、安全的 FTP 服务器,它以安全和配置简单为设计目标,支持虚拟主机,IPV6,PAM 等功能",
Slug: "pureftpd",
Version: "1.0.50",
Requires: []string{},
@@ -158,7 +158,7 @@ var PluginPureFTPd = Plugin{
var PluginRedis = Plugin{
Name: "Redis",
Description: "Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API",
Description: "Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API",
Slug: "redis",
Version: "7.2.5",
Requires: []string{},
@@ -170,7 +170,7 @@ var PluginRedis = Plugin{
var PluginS3fs = Plugin{
Name: "S3fs",
Description: "S3fs 通过 FUSE 挂载兼容 S3 标准的存储桶,例如 Amazon S3、阿里云 OSS、腾讯云 COS、七牛云 Kodo 等",
Description: "S3fs 通过 FUSE 挂载兼容 S3 标准的存储桶,例如 Amazon S3、阿里云 OSS、腾讯云 COS、七牛云 Kodo 等",
Slug: "s3fs",
Version: "1.9",
Requires: []string{},
@@ -182,7 +182,7 @@ var PluginS3fs = Plugin{
var PluginRsync = Plugin{
Name: "Rsync",
Description: "Rsync 是一款提供快速增量文件传输的开源工具",
Description: "Rsync 是一款提供快速增量文件传输的开源工具",
Slug: "rsync",
Version: "3.2.7",
Requires: []string{},
@@ -194,7 +194,7 @@ var PluginRsync = Plugin{
var PluginSupervisor = Plugin{
Name: "Supervisor",
Description: "Supervisor 是一个客户端/服务器系统,允许用户监视和控制类 UNIX 操作系统上的多个进程",
Description: "Supervisor 是一个客户端/服务器系统,允许用户监视和控制类 UNIX 操作系统上的多个进程",
Slug: "supervisor",
Version: "4.2.5",
Requires: []string{},
@@ -206,7 +206,7 @@ var PluginSupervisor = Plugin{
var PluginFail2ban = Plugin{
Name: "Fail2ban",
Description: "Fail2ban 扫描系统日志文件并从中找出多次尝试失败的IP地址,将该IP地址加入防火墙的拒绝访问列表中",
Description: "Fail2ban 扫描系统日志文件并从中找出多次尝试失败的IP地址,将该IP地址加入防火墙的拒绝访问列表中",
Slug: "fail2ban",
Version: "1.0.2",
Requires: []string{},
@@ -216,28 +216,40 @@ var PluginFail2ban = Plugin{
Update: `bash /www/panel/scripts/fail2ban/update.sh`,
}
var PluginPodman = Plugin{
Name: "Podman",
Description: "PodmanPOD MANager)是一款用于管理容器和镜像、挂载到这些容器中的卷以及由容器组构成的 Pod 的工具",
Slug: "podman",
Version: "4.0.0",
Requires: []string{},
Excludes: []string{"docker"},
Install: `bash /www/panel/scripts/podman/install.sh`,
Uninstall: `bash /www/panel/scripts/podman/uninstall.sh`,
Update: `bash /www/panel/scripts/podman/update.sh`,
}
var PluginFrp = Plugin{
Name: "Frp",
Description: "frp 是一个专注于内网穿透的高性能的反向代理应用",
Description: "frp 是一个专注于内网穿透的高性能的反向代理应用",
Slug: "frp",
Version: "0.58.0",
Requires: []string{},
Excludes: []string{},
Install: `bash /www/panel/scripts/frp/install.sh`,
Uninstall: `bash /www/panel/scripts/frp/uninstall.sh`,
Update: `bash /www/panel/scripts/frp/install.sh`,
Update: `bash /www/panel/scripts/frp/update.sh`,
}
var PluginGitea = Plugin{
Name: "Gitea",
Description: "Gitea 是一款极易搭建的自助 Git 服务,它包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD",
Description: "Gitea 是一款极易搭建的自助 Git 服务,它包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD",
Slug: "gitea",
Version: "1.22.0",
Requires: []string{},
Excludes: []string{},
Install: `bash /www/panel/scripts/gitea/install.sh`,
Uninstall: `bash /www/panel/scripts/gitea/uninstall.sh`,
Update: `bash /www/panel/scripts/gitea/install.sh`,
Update: `bash /www/panel/scripts/gitea/update.sh`,
}
var PluginToolBox = Plugin{