Compare commits
74 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
30cb471629 | ||
![]() |
d70c22dde8 | ||
![]() |
01bb6b7c01 | ||
![]() |
4f4879759e | ||
![]() |
92a410fcea | ||
![]() |
5d1fced8e9 | ||
![]() |
a56e5a8abe | ||
![]() |
28ae7f3a0c | ||
![]() |
8d675c81c5 | ||
![]() |
66a345364f | ||
![]() |
a3cb8be08f | ||
![]() |
0861b30a7b | ||
![]() |
36f2a3eb4b | ||
![]() |
092cbbf8da | ||
![]() |
39e3e8f214 | ||
![]() |
fa983bdcc9 | ||
![]() |
67bb30c10c | ||
![]() |
e85340ca5d | ||
![]() |
a3a1e17849 | ||
![]() |
2601135225 | ||
![]() |
c556affc91 | ||
![]() |
6ee9789a2f | ||
![]() |
68a457ae89 | ||
![]() |
72237596f3 | ||
![]() |
f516333682 | ||
![]() |
873af25684 | ||
![]() |
8b058a873e | ||
![]() |
0c5a5a6454 | ||
![]() |
2096049708 | ||
![]() |
1095aa2b65 | ||
![]() |
13679ff301 | ||
![]() |
89b7a06662 | ||
![]() |
e8582bea75 | ||
![]() |
9af7926eb9 | ||
![]() |
bdcdf7e181 | ||
![]() |
887db0aff7 | ||
![]() |
4a974b7e0a | ||
![]() |
fb286d2def | ||
![]() |
89cb9e6693 | ||
![]() |
927def4472 | ||
![]() |
84fcd31704 | ||
![]() |
005e5cc01f | ||
![]() |
2896409b3a | ||
![]() |
791641f3e1 | ||
![]() |
79f266bbda | ||
![]() |
c9edaf0d1d | ||
![]() |
ac5f73c687 | ||
![]() |
cc0667429a | ||
![]() |
92a5d6faeb | ||
![]() |
1111b6b494 | ||
![]() |
be5a7c99e1 | ||
![]() |
d6a963c087 | ||
![]() |
af753bdffe | ||
![]() |
59b025353f | ||
![]() |
355a6b0205 | ||
![]() |
7de80e9d5a | ||
![]() |
4c6d8cd20c | ||
![]() |
31da89d63a | ||
![]() |
e044ca7d12 | ||
![]() |
7c037b68cd | ||
![]() |
9080824a59 | ||
![]() |
11f4bc2c89 | ||
![]() |
a64ddd1eb8 | ||
![]() |
2fdaecfafe | ||
![]() |
6d1fe20736 | ||
![]() |
f61bc047cd | ||
![]() |
4f52580938 | ||
![]() |
281d0cf880 | ||
![]() |
fdf9215d43 | ||
![]() |
8c182e907d | ||
![]() |
e55af04568 | ||
![]() |
2462ffdbab | ||
![]() |
bfeb57e24f | ||
![]() |
9bb28cda27 |
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -25,7 +25,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
attributes:
|
attributes:
|
||||||
label: "1Panel 版本"
|
label: "1Panel 版本"
|
||||||
description: "可通过系统右上角下拉菜单中的`关于`选项,或查看安装目录中的 version 文件获取。"
|
description: "登录 1Panel Web 控制台,在页面右下角查看当前版本。"
|
||||||
- type: markdown
|
- type: markdown
|
||||||
id: details
|
id: details
|
||||||
attributes:
|
attributes:
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
2
.github/ISSUE_TEMPLATE/feature.yml
vendored
@@ -14,7 +14,7 @@ body:
|
|||||||
required: true
|
required: true
|
||||||
attributes:
|
attributes:
|
||||||
label: "1Panel 版本"
|
label: "1Panel 版本"
|
||||||
description: "可通过系统右上角下拉菜单中的`关于`选项,或查看安装目录中的 version 文件获取。"
|
description: "登录 1Panel Web 控制台,在页面右下角查看当前版本。"
|
||||||
- type: markdown
|
- type: markdown
|
||||||
id: details
|
id: details
|
||||||
attributes:
|
attributes:
|
||||||
|
17
.github/workflows/add-labels-for-pr.yml
vendored
Normal file
17
.github/workflows/add-labels-for-pr.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
on: pull_request
|
||||||
|
|
||||||
|
name: 1Panel 通用 PR 处理
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generic_handler:
|
||||||
|
name: 为 PR 添加标签
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions-ecosystem/action-add-labels@v1
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUBTOKEN }}
|
||||||
|
labels: ${{ github.base_ref }}
|
17
.github/workflows/issue-recent-alert.yml
vendored
Normal file
17
.github/workflows/issue-recent-alert.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 1 * * *"
|
||||||
|
|
||||||
|
name: Check recent handle issues
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-recent-issues-not-handle:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check recent issues and send msg
|
||||||
|
uses: jumpserver/action-issues-alert@master
|
||||||
|
with:
|
||||||
|
hook: ${{ secrets.WECHAT_GROUP_WEB_HOOK }}
|
||||||
|
type: recent
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
17
.github/workflows/issue-untimely-alert.yml
vendored
Normal file
17
.github/workflows/issue-untimely-alert.yml
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 9 * * 1-5"
|
||||||
|
|
||||||
|
name: Check untimely handle issues
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-untimely-handle-issues:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check untimely issues and send msg
|
||||||
|
uses: jumpserver/action-issues-alert@master
|
||||||
|
with:
|
||||||
|
hook: ${{ secrets.WECHAT_GROUP_WEB_HOOK }}
|
||||||
|
type: untimely
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
16
.github/workflows/sync2gitee.yml
vendored
Normal file
16
.github/workflows/sync2gitee.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
name: sync2gitee
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
repo-sync:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Mirror the Github organization repos to Gitee.
|
||||||
|
uses: Yikun/hub-mirror-action@master
|
||||||
|
with:
|
||||||
|
src: 'github/1Panel-dev'
|
||||||
|
dst: 'gitee/fit2cloud-xlab'
|
||||||
|
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
|
||||||
|
dst_token: ${{ secrets.GITEE_TOKEN }}
|
||||||
|
static_list: "1Panel"
|
||||||
|
force_update: true
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,5 +22,4 @@ cmd/server/__debug_bin
|
|||||||
cmd/server/web/assets
|
cmd/server/web/assets
|
||||||
cmd/server/web/monacoeditorwork
|
cmd/server/web/monacoeditorwork
|
||||||
cmd/server/web/index.html
|
cmd/server/web/index.html
|
||||||
cmd/server/web/favicon.png
|
|
||||||
frontend/auto-imports.d.ts
|
frontend/auto-imports.d.ts
|
||||||
|
11
OWNERS
Normal file
11
OWNERS
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
reviewers:
|
||||||
|
- zhengkunwang223
|
||||||
|
- ssongliu
|
||||||
|
- wanghe-fit2cloud
|
||||||
|
- wangdan-fit2cloud
|
||||||
|
|
||||||
|
approvers:
|
||||||
|
- zhengkunwang223
|
||||||
|
- ssongliu
|
||||||
|
- wanghe-fit2cloud
|
||||||
|
- wangdan-fit2cloud
|
23
README.md
23
README.md
@@ -1,3 +1,4 @@
|
|||||||
|
[README_EN.md](README_EN.md)
|
||||||
<p align="center"><a href="https://1panel.cn"><img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
<p align="center"><a href="https://1panel.cn"><img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
||||||
<p align="center"><b>现代化、开源的 Linux 服务器运维管理面板</b></p>
|
<p align="center"><b>现代化、开源的 Linux 服务器运维管理面板</b></p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -11,14 +12,14 @@
|
|||||||
|
|
||||||
1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。1Panel 的功能和优势包括:
|
1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。1Panel 的功能和优势包括:
|
||||||
|
|
||||||
- **快速建站**:深度集成 Wordpress 和 Halo,域名绑定、SSL 证书配置等一键搞定;
|
- **快速建站**:深度集成 Wordpress 和 [Halo](https://github.com/halo-dev/halo/),域名绑定、SSL 证书配置等一键搞定;
|
||||||
- **高效管理**:通过 Web 端轻松管理 Linux 服务器,包括主机监控、文件管理、数据库管理、容器管理及常用应用软件管理;
|
- **高效管理**:通过 Web 端轻松管理 Linux 服务器,包括应用管理、主机监控、文件管理、数据库管理、容器管理等;
|
||||||
- **安全可靠**:最小漏洞暴露面,提供防火墙和安全审计等功能;
|
- **安全可靠**:最小漏洞暴露面,提供防火墙和安全审计等功能;
|
||||||
- **一键备份**:支持一键备份和恢复,备份数据云端存储,永不丢失。
|
- **一键备份**:支持一键备份和恢复,备份数据云端存储,永不丢失。
|
||||||
|
|
||||||
## UI 展示
|
## UI 展示
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
|
|
||||||
@@ -30,16 +31,16 @@
|
|||||||
|
|
||||||
**一键安装**
|
**一键安装**
|
||||||
|
|
||||||
以 root 用户执行如下命令一键安装 1Panel:
|
执行如下命令一键安装 1Panel:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sh quick_start.sh
|
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
**学习资料**
|
**学习资料**
|
||||||
|
|
||||||
- [在线文档](https://1panel.cn/docs/)
|
- [在线文档](https://1panel.cn/docs/)
|
||||||
- [入门视频](https://1panel.cn/video.html)
|
- [教学视频](https://space.bilibili.com/510493147/channel/collectiondetail?sid=1199760)
|
||||||
|
|
||||||
## 社区
|
## 社区
|
||||||
|
|
||||||
@@ -47,18 +48,22 @@ curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_
|
|||||||
|
|
||||||
**微信交流群**
|
**微信交流群**
|
||||||
|
|
||||||
<img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/wechat-group.jpg" width="156" height="156"/>
|
<img src="https://1panel.cn/img/wechat-group.jpg" width="156" height="156"/>
|
||||||
|
|
||||||
## 安全说明
|
## 安全说明
|
||||||
|
|
||||||
如果您在使用过程中发现任何安全问题,请通过以下方式直接联系我们:
|
如果您在使用过程中发现任何安全问题,请通过以下方式直接联系我们:
|
||||||
|
|
||||||
- 邮箱:support@fit2cloud.com
|
- 邮箱:support@fit2cloud.com
|
||||||
- 电话:400-052-0755
|
- 电话:400-052-0755
|
||||||
|
|
||||||
|
## Star History
|
||||||
|
|
||||||
|
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (c) 2014-2023 飞致云 FIT2CLOUD, All rights reserved.
|
Copyright (c) 2014-2023 [FIT2CLOUD 飞致云](https://fit2cloud.com/), All rights reserved.
|
||||||
|
|
||||||
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
72
README_EN.md
Normal file
72
README_EN.md
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
[中文 README.md](README.md)
|
||||||
|
<p align="center"><a href="https://1panel.cn"><img src="http://1panel.oss-cn-hangzhou.aliyuncs.com/img/1panel-logo.png" alt="1Panel" width="300" /></a></p>
|
||||||
|
<p align="center"><b>Modern and Open-Source Linux Server Operation and Management Panel</b></p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://shields.io/github/license/1Panel-dev/1Panel" alt="License: GPL v3"></a>
|
||||||
|
<a href="https://app.codacy.com/gh/1Panel-dev/1Panel?utm_source=github.com&utm_medium=referral&utm_content=1Panel-dev/1Panel&utm_campaign=Badge_Grade_Dashboard"><img src="https://app.codacy.com/project/badge/Grade/da67574fd82b473992781d1386b937ef" alt="Codacy"></a>
|
||||||
|
<a href="https://github.com/1Panel-dev/1Panel/releases"><img src="https://img.shields.io/github/v/release/1Panel-dev/1Panel" alt="GitHub release"></a>
|
||||||
|
<a href="https://github.com/1Panel-dev/1Panel"><img src="https://img.shields.io/github/stars/1Panel-dev/1Panel?color=%231890FF&style=flat-square" alt="Stars"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
1Panel is a modern and Open-Source linux server operation and management panel, the functions and advantages of 1Panel include:
|
||||||
|
|
||||||
|
- **Quick website building**: Deeply integrated with Wordpress and [Halo](https://github.com/halo-dev/halo/), with one-click solutions for domain name binding, SSL certificate configuration, and more;
|
||||||
|
- **Efficient management**: Easily manage Linux servers through the web interface, including application management, host monitoring, file management, database management, container management, and more;
|
||||||
|
- **Secure and reliable**: Minimal vulnerability exposure, with firewall and security audit functions provided;
|
||||||
|
- **One-click backup**: Support for one-click backup and restore, with backup data stored in the cloud and never lost.
|
||||||
|
|
||||||
|
## UI Display
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
**Online Demo**
|
||||||
|
|
||||||
|
- Address: <https://demo.1panel.cn/>
|
||||||
|
- Username: demo
|
||||||
|
- Password: 1panel
|
||||||
|
|
||||||
|
**One-Click Installation**
|
||||||
|
|
||||||
|
Execute the following command to install 1Panel with one click:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
**Learning Materials**
|
||||||
|
|
||||||
|
- [Online Documentation](https://1panel.cn/docs/)
|
||||||
|
- [Teaching Videos](https://space.bilibili.com/510493147/channel/collectiondetail?sid=1199760)
|
||||||
|
|
||||||
|
## Community
|
||||||
|
|
||||||
|
If you have any questions or suggestions, please submit a GitHub Issue or join our WeChat group for communication.
|
||||||
|
|
||||||
|
**WeChat Group**
|
||||||
|
|
||||||
|
<img src="https://1panel.cn/img/wechat-group.jpg" width="156" height="156"/>
|
||||||
|
|
||||||
|
## Security Information
|
||||||
|
|
||||||
|
If you discover any security issues, please contact us through:
|
||||||
|
|
||||||
|
- Email: support@fit2cloud.com
|
||||||
|
- Phone: 400-052-0755
|
||||||
|
|
||||||
|
## Star History
|
||||||
|
|
||||||
|
[](https://star-history.com/#1Panel-dev/1Panel&Date)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Copyright (c) 2014-2023 [FIT2CLOUD 飞致云](https://fit2cloud.com/), All rights reserved.
|
||||||
|
|
||||||
|
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
<https://www.gnu.org/licenses/gpl-3.0.html>
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
19
SECURITY.md
Normal file
19
SECURITY.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# 安全说明
|
||||||
|
|
||||||
|
如果您发现安全问题,请直接联系我们:
|
||||||
|
|
||||||
|
- wanghe@fit2cloud.com
|
||||||
|
- support@fit2cloud.com
|
||||||
|
- 400-052-0755
|
||||||
|
|
||||||
|
感谢您的支持!
|
||||||
|
|
||||||
|
# Security Policy
|
||||||
|
|
||||||
|
All security bugs should be reported to the contact as below:
|
||||||
|
|
||||||
|
- wanghe@fit2cloud.com
|
||||||
|
- support@fit2cloud.com
|
||||||
|
- 400-052-0755
|
||||||
|
|
||||||
|
Thanks for your support!
|
@@ -144,7 +144,7 @@ func (b *BaseApi) DeleteCheck(c *gin.Context) {
|
|||||||
// @Router /apps/installed/sync [post]
|
// @Router /apps/installed/sync [post]
|
||||||
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"同步已安装应用列表","formatEN":"Sync the list of installed apps"}
|
// @x-panel-log {"bodyKeys":[],"paramKeys":[],"BeforeFuntions":[],"formatZH":"同步已安装应用列表","formatEN":"Sync the list of installed apps"}
|
||||||
func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
func (b *BaseApi) SyncInstalled(c *gin.Context) {
|
||||||
if err := appInstallService.SyncAll(); err != nil {
|
if err := appInstallService.SyncAll(false); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
@@ -27,6 +29,23 @@ func (b *BaseApi) CreateBackup(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(req.Credential) != 0 {
|
||||||
|
credential, err := base64.StdEncoding.DecodeString(req.Credential)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Credential = string(credential)
|
||||||
|
}
|
||||||
|
if len(req.AccessKey) != 0 {
|
||||||
|
accessKey, err := base64.StdEncoding.DecodeString(req.AccessKey)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.AccessKey = string(accessKey)
|
||||||
|
}
|
||||||
|
|
||||||
if err := backupService.Create(req); err != nil {
|
if err := backupService.Create(req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
@@ -52,6 +71,23 @@ func (b *BaseApi) ListBuckets(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(req.Credential) != 0 {
|
||||||
|
credential, err := base64.StdEncoding.DecodeString(req.Credential)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Credential = string(credential)
|
||||||
|
}
|
||||||
|
if len(req.AccessKey) != 0 {
|
||||||
|
accessKey, err := base64.StdEncoding.DecodeString(req.AccessKey)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.AccessKey = string(accessKey)
|
||||||
|
}
|
||||||
|
|
||||||
buckets, err := backupService.GetBuckets(req)
|
buckets, err := backupService.GetBuckets(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
@@ -139,7 +175,7 @@ func (b *BaseApi) DownloadRecord(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.File(filePath)
|
helper.SuccessWithData(c, filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Backup Account
|
// @Tags Backup Account
|
||||||
@@ -188,6 +224,23 @@ func (b *BaseApi) UpdateBackup(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(req.Credential) != 0 {
|
||||||
|
credential, err := base64.StdEncoding.DecodeString(req.Credential)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Credential = string(credential)
|
||||||
|
}
|
||||||
|
if len(req.AccessKey) != 0 {
|
||||||
|
accessKey, err := base64.StdEncoding.DecodeString(req.AccessKey)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.AccessKey = string(accessKey)
|
||||||
|
}
|
||||||
|
|
||||||
if err := backupService.Update(req); err != nil {
|
if err := backupService.Update(req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
|
@@ -70,6 +70,34 @@ func (b *BaseApi) SearchCompose(c *gin.Context) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Container Compose
|
||||||
|
// @Summary Test compose
|
||||||
|
// @Description 测试 compose 是否可用
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.ComposeCreate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /containers/compose/test [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测 compose [name] 格式","formatEN":"check compose [name]"}
|
||||||
|
func (b *BaseApi) TestCompose(c *gin.Context) {
|
||||||
|
var req dto.ComposeCreate
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := global.VALID.Struct(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isOK, err := containerService.TestCompose(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, isOK)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Container Compose
|
// @Tags Container Compose
|
||||||
// @Summary Create compose
|
// @Summary Create compose
|
||||||
// @Description 创建容器编排
|
// @Description 创建容器编排
|
||||||
@@ -90,11 +118,12 @@ func (b *BaseApi) CreateCompose(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := containerService.CreateCompose(req); err != nil {
|
log, err := containerService.CreateCompose(req)
|
||||||
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
helper.SuccessWithData(c, nil)
|
helper.SuccessWithData(c, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Container Compose
|
// @Tags Container Compose
|
||||||
|
@@ -198,7 +198,7 @@ func (b *BaseApi) TargetDownload(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.File(filePath)
|
helper.SuccessWithData(c, filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Tags Cronjob
|
// @Tags Cronjob
|
||||||
|
@@ -2,6 +2,7 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
@@ -29,6 +30,15 @@ func (b *BaseApi) CreateMysql(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := mysqlService.Create(context.Background(), req); err != nil {
|
if _, err := mysqlService.Create(context.Background(), req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
@@ -81,6 +91,15 @@ func (b *BaseApi) ChangeMysqlPassword(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(req.Value) != 0 {
|
||||||
|
value, err := base64.StdEncoding.DecodeString(req.Value)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Value = string(value)
|
||||||
|
}
|
||||||
|
|
||||||
if err := mysqlService.ChangePassword(req); err != nil {
|
if err := mysqlService.ChangePassword(req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
|
@@ -2,6 +2,7 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@@ -106,6 +107,15 @@ func (b *BaseApi) ChangeRedisPassword(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(req.Value) != 0 {
|
||||||
|
value, err := base64.StdEncoding.DecodeString(req.Value)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Value = string(value)
|
||||||
|
}
|
||||||
|
|
||||||
if err := redisService.ChangePassword(req); err != nil {
|
if err := redisService.ChangePassword(req); err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
return
|
return
|
||||||
|
@@ -35,7 +35,6 @@ var (
|
|||||||
|
|
||||||
commandService = service.ServiceGroupApp.CommandService
|
commandService = service.ServiceGroupApp.CommandService
|
||||||
|
|
||||||
websiteGroupService = service.ServiceGroupApp.WebsiteGroupService
|
|
||||||
websiteService = service.ServiceGroupApp.WebsiteService
|
websiteService = service.ServiceGroupApp.WebsiteService
|
||||||
websiteDnsAccountService = service.ServiceGroupApp.WebsiteDnsAccountService
|
websiteDnsAccountService = service.ServiceGroupApp.WebsiteDnsAccountService
|
||||||
websiteSSLService = service.ServiceGroupApp.WebsiteSSLService
|
websiteSSLService = service.ServiceGroupApp.WebsiteSSLService
|
||||||
|
@@ -3,6 +3,14 @@ package v1
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
@@ -14,13 +22,6 @@ import (
|
|||||||
websocket2 "github.com/1Panel-dev/1Panel/backend/utils/websocket"
|
websocket2 "github.com/1Panel-dev/1Panel/backend/utils/websocket"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
@@ -444,6 +445,28 @@ func (b *BaseApi) Download(c *gin.Context) {
|
|||||||
c.File(filePath)
|
c.File(filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Download file with path
|
||||||
|
// @Description 下载指定文件
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.FilePath true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /files/download/bypath [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"下载文件 [path]","formatEN":"Download file [path]"}
|
||||||
|
func (b *BaseApi) DownloadFile(c *gin.Context) {
|
||||||
|
var req dto.FilePath
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := global.VALID.Struct(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.File(req.Path)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Load file size
|
// @Summary Load file size
|
||||||
// @Description 获取文件夹大小
|
// @Description 获取文件夹大小
|
||||||
@@ -496,6 +519,12 @@ func (b *BaseApi) LoadFromFile(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int) error {
|
func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int) error {
|
||||||
|
if _, err := os.Stat(path.Dir(dstDir)); err != nil && os.IsNotExist(err) {
|
||||||
|
if err = os.MkdirAll(path.Dir(dstDir), os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
targetFile, err := os.Create(filepath.Join(dstDir, fileName))
|
targetFile, err := os.Create(filepath.Join(dstDir, fileName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -524,7 +553,6 @@ func mergeChunks(fileName string, fileDir string, dstDir string, chunkCount int)
|
|||||||
// @Success 200
|
// @Success 200
|
||||||
// @Security ApiKeyAuth
|
// @Security ApiKeyAuth
|
||||||
// @Router /files/chunkupload [post]
|
// @Router /files/chunkupload [post]
|
||||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"上传文件 [path]","formatEN":"Upload file [path]"}
|
|
||||||
func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
||||||
fileForm, err := c.FormFile("chunk")
|
fileForm, err := c.FormFile("chunk")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -550,15 +578,18 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
if err := fileOp.CreateDir("uploads", 0755); err != nil {
|
tmpDir := path.Join(global.CONF.System.TmpDir, "upload")
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
if !fileOp.Stat(tmpDir) {
|
||||||
return
|
if err := fileOp.CreateDir(tmpDir, 0755); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//fileID := uuid.New().String()
|
|
||||||
filename := c.PostForm("filename")
|
|
||||||
fileDir := filepath.Join(global.CONF.System.DataDir, "upload", filename)
|
|
||||||
|
|
||||||
os.MkdirAll(fileDir, 0755)
|
filename := c.PostForm("filename")
|
||||||
|
fileDir := filepath.Join(tmpDir, filename)
|
||||||
|
|
||||||
|
_ = os.MkdirAll(fileDir, 0755)
|
||||||
filePath := filepath.Join(fileDir, filename)
|
filePath := filepath.Join(fileDir, filename)
|
||||||
|
|
||||||
emptyFile, err := os.Create(filePath)
|
emptyFile, err := os.Create(filePath)
|
||||||
@@ -566,26 +597,25 @@ func (b *BaseApi) UploadChunkFiles(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
emptyFile.Close()
|
defer emptyFile.Close()
|
||||||
|
|
||||||
chunkData, err := ioutil.ReadAll(uploadFile)
|
chunkData, err := ioutil.ReadAll(uploadFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrFileUpload, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", filename, chunkIndex))
|
chunkPath := filepath.Join(fileDir, fmt.Sprintf("%s.%d", filename, chunkIndex))
|
||||||
err = ioutil.WriteFile(chunkPath, chunkData, 0644)
|
err = ioutil.WriteFile(chunkPath, chunkData, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrFileUpload, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if chunkIndex+1 == chunkCount {
|
if chunkIndex+1 == chunkCount {
|
||||||
err = mergeChunks(filename, fileDir, c.PostForm("path"), chunkCount)
|
err = mergeChunks(filename, fileDir, c.PostForm("path"), chunkCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrFileUpload, err)
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrAppDelete, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
helper.SuccessWithData(c, true)
|
helper.SuccessWithData(c, true)
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
@@ -29,6 +31,23 @@ func (b *BaseApi) CreateHost(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||||
|
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.PrivateKey = string(privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
host, err := hostService.Create(req)
|
host, err := hostService.Create(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
@@ -55,6 +74,22 @@ func (b *BaseApi) TestByInfo(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||||
|
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.PrivateKey = string(privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
var connInfo ssh.ConnInfo
|
var connInfo ssh.ConnInfo
|
||||||
_ = copier.Copy(&connInfo, &req)
|
_ = copier.Copy(&connInfo, &req)
|
||||||
@@ -211,6 +246,22 @@ func (b *BaseApi) UpdateHost(c *gin.Context) {
|
|||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if req.AuthMode == "password" && len(req.Password) != 0 {
|
||||||
|
password, err := base64.StdEncoding.DecodeString(req.Password)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Password = string(password)
|
||||||
|
}
|
||||||
|
if req.AuthMode == "key" && len(req.PrivateKey) != 0 {
|
||||||
|
privateKey, err := base64.StdEncoding.DecodeString(req.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.PrivateKey = string(privateKey)
|
||||||
|
}
|
||||||
|
|
||||||
upMap := make(map[string]interface{})
|
upMap := make(map[string]interface{})
|
||||||
upMap["name"] = req.Name
|
upMap["name"] = req.Name
|
||||||
|
@@ -22,6 +22,28 @@ func (b *BaseApi) GetUpgradeInfo(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, info)
|
helper.SuccessWithData(c, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags System Setting
|
||||||
|
// @Summary Load release notes by version
|
||||||
|
// @Description 获取版本 release notes
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body dto.Upgrade true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /settings/upgrade [get]
|
||||||
|
func (b *BaseApi) GetNotesByVersion(c *gin.Context) {
|
||||||
|
var req dto.Upgrade
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
notes, err := upgradeService.LoadNotes(req)
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, notes)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags System Setting
|
// @Tags System Setting
|
||||||
// @Summary Upgrade
|
// @Summary Upgrade
|
||||||
// @Description 系统更新
|
// @Description 系统更新
|
||||||
|
@@ -1,89 +0,0 @@
|
|||||||
package v1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// @Tags Website Group
|
|
||||||
// @Summary List website groups
|
|
||||||
// @Description 获取网站组
|
|
||||||
// @Success 200 {anrry} model.WebsiteGroup
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /websites/groups [get]
|
|
||||||
func (b *BaseApi) GetWebGroups(c *gin.Context) {
|
|
||||||
list, err := websiteGroupService.GetGroups()
|
|
||||||
if err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, list)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Website Group
|
|
||||||
// @Summary Create website group
|
|
||||||
// @Description 创建网站组
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body request.WebsiteGroupCreate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /websites/groups [post]
|
|
||||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"创建网站组 [name]","formatEN":"Create website groups [name]"}
|
|
||||||
func (b *BaseApi) CreateWebGroup(c *gin.Context) {
|
|
||||||
var req request.WebsiteGroupCreate
|
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := websiteGroupService.CreateGroup(req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Website Group
|
|
||||||
// @Summary Update website group
|
|
||||||
// @Description 更新网站组
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body request.WebsiteGroupUpdate true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /websites/groups/update [post]
|
|
||||||
// @x-panel-log {"bodyKeys":["name"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"更新网站组 [name]","formatEN":"Update website groups [name]"}
|
|
||||||
func (b *BaseApi) UpdateWebGroup(c *gin.Context) {
|
|
||||||
var req request.WebsiteGroupUpdate
|
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := websiteGroupService.UpdateGroup(req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Tags Website Group
|
|
||||||
// @Summary Delete website group
|
|
||||||
// @Description 删除网站组
|
|
||||||
// @Accept json
|
|
||||||
// @Param request body request.WebsiteResourceReq true "request"
|
|
||||||
// @Success 200
|
|
||||||
// @Security ApiKeyAuth
|
|
||||||
// @Router /websites/groups/del [post]
|
|
||||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_groups","output_colume":"name","output_value":"name"}],"formatZH":"删除网站组 [name]","formatEN":"Delete website group [name]"}
|
|
||||||
func (b *BaseApi) DeleteWebGroup(c *gin.Context) {
|
|
||||||
var req request.WebsiteResourceReq
|
|
||||||
if err := c.ShouldBindJSON(&req); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := websiteGroupService.DeleteGroup(req.ID); err != nil {
|
|
||||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
helper.SuccessWithData(c, nil)
|
|
||||||
}
|
|
@@ -176,3 +176,25 @@ func (b *BaseApi) GetWebsiteSSLById(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithData(c, websiteSSL)
|
helper.SuccessWithData(c, websiteSSL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Website SSL
|
||||||
|
// @Summary Update ssl
|
||||||
|
// @Description 更新 ssl
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.WebsiteSSLUpdate true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /websites/ssl/update [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFuntions":[{"input_colume":"id","input_value":"id","isList":false,"db":"website_ssls","output_colume":"primary_domain","output_value":"domain"}],"formatZH":"更新证书设置 [domain]","formatEN":"Update ssl config [domain]"}
|
||||||
|
func (b *BaseApi) UpdateWebsiteSSL(c *gin.Context) {
|
||||||
|
var req request.WebsiteSSLUpdate
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := websiteSSLService.Update(req); err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, nil)
|
||||||
|
}
|
||||||
|
@@ -69,15 +69,21 @@ type AppForm struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppFormFields struct {
|
type AppFormFields struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
LabelZh string `json:"labelZh"`
|
LabelZh string `json:"labelZh"`
|
||||||
LabelEn string `json:"labelEn"`
|
LabelEn string `json:"labelEn"`
|
||||||
Required bool `json:"required"`
|
Required bool `json:"required"`
|
||||||
Default interface{} `json:"default"`
|
Default interface{} `json:"default"`
|
||||||
EnvKey string `json:"envKey"`
|
EnvKey string `json:"envKey"`
|
||||||
Disabled bool `json:"disabled"`
|
Disabled bool `json:"disabled"`
|
||||||
Edit bool `json:"edit"`
|
Edit bool `json:"edit"`
|
||||||
Rule string `json:"rule"`
|
Rule string `json:"rule"`
|
||||||
|
Values []AppFormValue `json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppFormValue struct {
|
||||||
|
Label string `json:"label"`
|
||||||
|
Value string `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppResource struct {
|
type AppResource struct {
|
||||||
|
@@ -9,7 +9,6 @@ type UserLoginInfo struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
MfaStatus string `json:"mfaStatus"`
|
MfaStatus string `json:"mfaStatus"`
|
||||||
MfaSecret string `json:"mfaSecret"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MfaCredential struct {
|
type MfaCredential struct {
|
||||||
@@ -28,7 +27,6 @@ type Login struct {
|
|||||||
type MFALogin struct {
|
type MFALogin struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Secret string `json:"secret"`
|
|
||||||
Code string `json:"code"`
|
Code string `json:"code"`
|
||||||
AuthMethod string `json:"authMethod"`
|
AuthMethod string `json:"authMethod"`
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ type ContainerInfo struct {
|
|||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
RunTime string `json:"runTime"`
|
RunTime string `json:"runTime"`
|
||||||
|
|
||||||
|
IsFromApp bool `json:"isFromApp"`
|
||||||
IsFromCompose bool `json:"isFromCompose"`
|
IsFromCompose bool `json:"isFromCompose"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ type GroupSearch struct {
|
|||||||
type GroupUpdate struct {
|
type GroupUpdate struct {
|
||||||
ID uint `json:"id"`
|
ID uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type" validate:"required"`
|
||||||
IsDefault bool `json:"isDefault"`
|
IsDefault bool `json:"isDefault"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -44,3 +44,8 @@ type WebsiteDnsAccountUpdate struct {
|
|||||||
type WebsiteResourceReq struct {
|
type WebsiteResourceReq struct {
|
||||||
ID uint `json:"id" validate:"required"`
|
ID uint `json:"id" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebsiteSSLUpdate struct {
|
||||||
|
ID uint `json:"id" validate:"required"`
|
||||||
|
AutoRenew bool `json:"autoRenew" validate:"required"`
|
||||||
|
}
|
||||||
|
@@ -61,11 +61,13 @@ type AppService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AppParam struct {
|
type AppParam struct {
|
||||||
Value interface{} `json:"value"`
|
Value interface{} `json:"value"`
|
||||||
Edit bool `json:"edit"`
|
Edit bool `json:"edit"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
Rule string `json:"rule"`
|
Rule string `json:"rule"`
|
||||||
LabelZh string `json:"labelZh"`
|
LabelZh string `json:"labelZh"`
|
||||||
LabelEn string `json:"labelEn"`
|
LabelEn string `json:"labelEn"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
|
Values interface{} `json:"values"`
|
||||||
|
ShowValue string `json:"showValue"`
|
||||||
}
|
}
|
||||||
|
@@ -82,9 +82,11 @@ type SnapshotInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UpgradeInfo struct {
|
type UpgradeInfo struct {
|
||||||
NewVersion string `json:"newVersion"`
|
NewVersion string `json:"newVersion"`
|
||||||
ReleaseNote string `json:"releaseNote"`
|
LatestVersion string `json:"latestVersion"`
|
||||||
|
ReleaseNote string `json:"releaseNote"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Upgrade struct {
|
type Upgrade struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type WebsiteGroup struct {
|
|
||||||
BaseModel
|
|
||||||
Name string `gorm:"type:varchar(64);not null" json:"name"`
|
|
||||||
Default bool `json:"default"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroup) TableName() string {
|
|
||||||
return "website_groups"
|
|
||||||
}
|
|
@@ -113,6 +113,7 @@ type RootInfo struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Port int64 `json:"port"`
|
Port int64 `json:"port"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
|
UserPassword string `json:"userPassword"`
|
||||||
ContainerName string `json:"containerName"`
|
ContainerName string `json:"containerName"`
|
||||||
Param string `json:"param"`
|
Param string `json:"param"`
|
||||||
Env string `json:"env"`
|
Env string `json:"env"`
|
||||||
@@ -146,6 +147,10 @@ func (a *AppInstallRepo) LoadBaseInfo(key string, name string) (*RootInfo, error
|
|||||||
if ok {
|
if ok {
|
||||||
info.Password = password
|
info.Password = password
|
||||||
}
|
}
|
||||||
|
userPassword, ok := envMap["PANEL_DB_USER_PASSWORD"].(string)
|
||||||
|
if ok {
|
||||||
|
info.UserPassword = userPassword
|
||||||
|
}
|
||||||
info.Port = int64(appInstall.HttpPort)
|
info.Port = int64(appInstall.HttpPort)
|
||||||
info.ID = appInstall.ID
|
info.ID = appInstall.ID
|
||||||
info.ContainerName = appInstall.ContainerName
|
info.ContainerName = appInstall.ContainerName
|
||||||
|
@@ -24,7 +24,7 @@ type ICronjobRepo interface {
|
|||||||
Update(id uint, vars map[string]interface{}) error
|
Update(id uint, vars map[string]interface{}) error
|
||||||
Delete(opts ...DBOption) error
|
Delete(opts ...DBOption) error
|
||||||
DeleteRecord(opts ...DBOption) error
|
DeleteRecord(opts ...DBOption) error
|
||||||
StartRecords(cronjobID uint, targetPath string) model.JobRecords
|
StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords
|
||||||
EndRecords(record model.JobRecords, status, message, records string)
|
EndRecords(record model.JobRecords, status, message, records string)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,10 +112,11 @@ func (c *CronjobRepo) WithByJobID(id int) DBOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *CronjobRepo) StartRecords(cronjobID uint, targetPath string) model.JobRecords {
|
func (u *CronjobRepo) StartRecords(cronjobID uint, fromLocal bool, targetPath string) model.JobRecords {
|
||||||
var record model.JobRecords
|
var record model.JobRecords
|
||||||
record.StartTime = time.Now()
|
record.StartTime = time.Now()
|
||||||
record.CronjobID = cronjobID
|
record.CronjobID = cronjobID
|
||||||
|
record.FromLocal = fromLocal
|
||||||
record.Status = constant.StatusWaiting
|
record.Status = constant.StatusWaiting
|
||||||
if err := global.DB.Create(&record).Error; err != nil {
|
if err := global.DB.Create(&record).Error; err != nil {
|
||||||
global.LOG.Errorf("create record status failed, err: %v", err)
|
global.LOG.Errorf("create record status failed, err: %v", err)
|
||||||
|
@@ -19,7 +19,6 @@ type RepoGroup struct {
|
|||||||
BackupRepo
|
BackupRepo
|
||||||
WebsiteRepo
|
WebsiteRepo
|
||||||
WebsiteDomainRepo
|
WebsiteDomainRepo
|
||||||
WebsiteGroupRepo
|
|
||||||
WebsiteDnsAccountRepo
|
WebsiteDnsAccountRepo
|
||||||
WebsiteSSLRepo
|
WebsiteSSLRepo
|
||||||
WebsiteAcmeAccountRepo
|
WebsiteAcmeAccountRepo
|
||||||
|
@@ -14,7 +14,7 @@ type IGroupRepo interface {
|
|||||||
Create(group *model.Group) error
|
Create(group *model.Group) error
|
||||||
Update(id uint, vars map[string]interface{}) error
|
Update(id uint, vars map[string]interface{}) error
|
||||||
Delete(opts ...DBOption) error
|
Delete(opts ...DBOption) error
|
||||||
CancelDefault() error
|
CancelDefault(groupType string) error
|
||||||
WithByIsDefault(isDefault bool) DBOption
|
WithByIsDefault(isDefault bool) DBOption
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +64,6 @@ func (u *GroupRepo) Delete(opts ...DBOption) error {
|
|||||||
return db.Delete(&model.Group{}).Error
|
return db.Delete(&model.Group{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w GroupRepo) CancelDefault() error {
|
func (u *GroupRepo) CancelDefault(groupType string) error {
|
||||||
return global.DB.Model(&model.Group{}).Where("`is_default` = 1").Updates(map[string]interface{}{"is_default": 0}).Error
|
return global.DB.Model(&model.Group{}).Where("is_default = ? AND type = ?", 1, groupType).Updates(map[string]interface{}{"is_default": 0}).Error
|
||||||
}
|
}
|
||||||
|
@@ -1,44 +0,0 @@
|
|||||||
package repo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
|
||||||
"gorm.io/gorm/clause"
|
|
||||||
)
|
|
||||||
|
|
||||||
type WebsiteGroupRepo struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupRepo) Page(page, size int, opts ...DBOption) (int64, []model.WebsiteGroup, error) {
|
|
||||||
var groups []model.WebsiteGroup
|
|
||||||
db := getDb(opts...).Model(&model.WebsiteGroup{})
|
|
||||||
count := int64(0)
|
|
||||||
db = db.Count(&count)
|
|
||||||
err := db.Limit(size).Offset(size * (page - 1)).Order("`default` desc").Find(&groups).Error
|
|
||||||
return count, groups, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupRepo) GetBy(opts ...DBOption) ([]model.WebsiteGroup, error) {
|
|
||||||
var groups []model.WebsiteGroup
|
|
||||||
db := getDb(opts...).Model(&model.WebsiteGroup{})
|
|
||||||
if err := db.Order("`default` desc").Find(&groups).Error; err != nil {
|
|
||||||
return groups, err
|
|
||||||
}
|
|
||||||
return groups, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupRepo) Create(app *model.WebsiteGroup) error {
|
|
||||||
return getDb().Omit(clause.Associations).Create(app).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupRepo) Save(app *model.WebsiteGroup) error {
|
|
||||||
return getDb().Omit(clause.Associations).Save(app).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupRepo) DeleteBy(opts ...DBOption) error {
|
|
||||||
return getDb(opts...).Delete(&model.WebsiteGroup{}).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupRepo) CancelDefault() error {
|
|
||||||
return global.DB.Model(&model.WebsiteGroup{}).Where("`default` = 1").Updates(map[string]interface{}{"default": 0}).Error
|
|
||||||
}
|
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@@ -166,6 +167,9 @@ func (a AppService) GetAppDetail(appId uint, version string) (response.AppDetail
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error) {
|
func (a AppService) Install(ctx context.Context, req request.AppInstallCreate) (*model.AppInstall, error) {
|
||||||
|
if err := docker.CreateDefaultDockerNetwork(); err != nil {
|
||||||
|
return nil, buserr.WithDetail(constant.Err1PanelNetworkFailed, err.Error(), nil)
|
||||||
|
}
|
||||||
if list, _ := appInstallRepo.ListBy(commonRepo.WithByName(req.Name)); len(list) > 0 {
|
if list, _ := appInstallRepo.ListBy(commonRepo.WithByName(req.Name)); len(list) > 0 {
|
||||||
return nil, buserr.New(constant.ErrNameIsExist)
|
return nil, buserr.New(constant.ErrNameIsExist)
|
||||||
}
|
}
|
||||||
|
@@ -3,9 +3,6 @@ package service
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/env"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
|
|
||||||
"github.com/joho/godotenv"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
@@ -14,6 +11,10 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/env"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
"github.com/1Panel-dev/1Panel/backend/app/dto/response"
|
||||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
@@ -33,7 +34,28 @@ import (
|
|||||||
type AppInstallService struct {
|
type AppInstallService struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) Page(req request.AppInstalledSearch) (int64, []response.AppInstalledDTO, error) {
|
type IAppInstallService interface {
|
||||||
|
Page(req request.AppInstalledSearch) (int64, []response.AppInstalledDTO, error)
|
||||||
|
CheckExist(key string) (*response.AppInstalledCheck, error)
|
||||||
|
LoadPort(key string) (int64, error)
|
||||||
|
LoadPassword(key string) (string, error)
|
||||||
|
SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error)
|
||||||
|
Operate(req request.AppInstalledOperate) error
|
||||||
|
Update(req request.AppInstalledUpdate) error
|
||||||
|
SyncAll(systemInit bool) error
|
||||||
|
GetServices(key string) ([]response.AppService, error)
|
||||||
|
GetUpdateVersions(installId uint) ([]dto.AppVersion, error)
|
||||||
|
GetParams(id uint) ([]response.AppParam, error)
|
||||||
|
ChangeAppPort(req request.PortUpdate) error
|
||||||
|
GetDefaultConfigByKey(key string) (string, error)
|
||||||
|
DeleteCheck(installId uint) ([]dto.AppResource, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIAppInstalledService() IAppInstallService {
|
||||||
|
return &AppInstallService{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AppInstallService) Page(req request.AppInstalledSearch) (int64, []response.AppInstalledDTO, error) {
|
||||||
var opts []repo.DBOption
|
var opts []repo.DBOption
|
||||||
|
|
||||||
if req.Name != "" {
|
if req.Name != "" {
|
||||||
@@ -73,7 +95,7 @@ func (a AppInstallService) Page(req request.AppInstalledSearch) (int64, []respon
|
|||||||
return total, installDTOs, nil
|
return total, installDTOs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) CheckExist(key string) (*response.AppInstalledCheck, error) {
|
func (a *AppInstallService) CheckExist(key string) (*response.AppInstalledCheck, error) {
|
||||||
res := &response.AppInstalledCheck{
|
res := &response.AppInstalledCheck{
|
||||||
IsExist: false,
|
IsExist: false,
|
||||||
}
|
}
|
||||||
@@ -103,7 +125,7 @@ func (a AppInstallService) CheckExist(key string) (*response.AppInstalledCheck,
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) LoadPort(key string) (int64, error) {
|
func (a *AppInstallService) LoadPort(key string) (int64, error) {
|
||||||
app, err := appInstallRepo.LoadBaseInfo(key, "")
|
app, err := appInstallRepo.LoadBaseInfo(key, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return int64(0), nil
|
return int64(0), nil
|
||||||
@@ -111,7 +133,7 @@ func (a AppInstallService) LoadPort(key string) (int64, error) {
|
|||||||
return app.Port, nil
|
return app.Port, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) LoadPassword(key string) (string, error) {
|
func (a *AppInstallService) LoadPassword(key string) (string, error) {
|
||||||
app, err := appInstallRepo.LoadBaseInfo(key, "")
|
app, err := appInstallRepo.LoadBaseInfo(key, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
@@ -119,7 +141,7 @@ func (a AppInstallService) LoadPassword(key string) (string, error) {
|
|||||||
return app.Password, nil
|
return app.Password, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error) {
|
func (a *AppInstallService) SearchForWebsite(req request.AppInstalledSearch) ([]response.AppInstalledDTO, error) {
|
||||||
var (
|
var (
|
||||||
installs []model.AppInstall
|
installs []model.AppInstall
|
||||||
err error
|
err error
|
||||||
@@ -152,7 +174,7 @@ func (a AppInstallService) SearchForWebsite(req request.AppInstalledSearch) ([]r
|
|||||||
return handleInstalled(installs, false)
|
return handleInstalled(installs, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) Operate(req request.AppInstalledOperate) error {
|
func (a *AppInstallService) Operate(req request.AppInstalledOperate) error {
|
||||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -196,7 +218,7 @@ func (a AppInstallService) Operate(req request.AppInstalledOperate) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) Update(req request.AppInstalledUpdate) error {
|
func (a *AppInstallService) Update(req request.AppInstalledUpdate) error {
|
||||||
installed, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
installed, err := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -270,13 +292,18 @@ func (a AppInstallService) Update(req request.AppInstalledUpdate) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) SyncAll() error {
|
func (a *AppInstallService) SyncAll(systemInit bool) error {
|
||||||
allList, err := appInstallRepo.ListBy()
|
allList, err := appInstallRepo.ListBy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, i := range allList {
|
for _, i := range allList {
|
||||||
if i.Status == constant.Installing {
|
if i.Status == constant.Installing {
|
||||||
|
if systemInit {
|
||||||
|
i.Status = constant.Error
|
||||||
|
i.Message = "System restart causes application exception"
|
||||||
|
_ = appInstallRepo.Save(&i)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := syncById(i.ID); err != nil {
|
if err := syncById(i.ID); err != nil {
|
||||||
@@ -286,7 +313,7 @@ func (a AppInstallService) SyncAll() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) GetServices(key string) ([]response.AppService, error) {
|
func (a *AppInstallService) GetServices(key string) ([]response.AppService, error) {
|
||||||
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
app, err := appRepo.GetFirst(appRepo.WithKey(key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -310,7 +337,7 @@ func (a AppInstallService) GetServices(key string) ([]response.AppService, error
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) GetUpdateVersions(installId uint) ([]dto.AppVersion, error) {
|
func (a *AppInstallService) GetUpdateVersions(installId uint) ([]dto.AppVersion, error) {
|
||||||
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
install, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||||
var versions []dto.AppVersion
|
var versions []dto.AppVersion
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -335,7 +362,7 @@ func (a AppInstallService) GetUpdateVersions(installId uint) ([]dto.AppVersion,
|
|||||||
return versions, nil
|
return versions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) ChangeAppPort(req request.PortUpdate) error {
|
func (a *AppInstallService) ChangeAppPort(req request.PortUpdate) error {
|
||||||
if common.ScanPort(int(req.Port)) {
|
if common.ScanPort(int(req.Port)) {
|
||||||
return buserr.WithDetail(constant.ErrPortInUsed, req.Port, nil)
|
return buserr.WithDetail(constant.ErrPortInUsed, req.Port, nil)
|
||||||
}
|
}
|
||||||
@@ -363,7 +390,7 @@ func (a AppInstallService) ChangeAppPort(req request.PortUpdate) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) DeleteCheck(installId uint) ([]dto.AppResource, error) {
|
func (a *AppInstallService) DeleteCheck(installId uint) ([]dto.AppResource, error) {
|
||||||
var res []dto.AppResource
|
var res []dto.AppResource
|
||||||
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(installId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -404,7 +431,7 @@ func (a AppInstallService) DeleteCheck(installId uint) ([]dto.AppResource, error
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) GetDefaultConfigByKey(key string) (string, error) {
|
func (a *AppInstallService) GetDefaultConfigByKey(key string) (string, error) {
|
||||||
appInstall, err := getAppInstallByKey(key)
|
appInstall, err := getAppInstallByKey(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -426,7 +453,7 @@ func (a AppInstallService) GetDefaultConfigByKey(key string) (string, error) {
|
|||||||
return string(contentByte), nil
|
return string(contentByte), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a AppInstallService) GetParams(id uint) ([]response.AppParam, error) {
|
func (a *AppInstallService) GetParams(id uint) ([]response.AppParam, error) {
|
||||||
var (
|
var (
|
||||||
res []response.AppParam
|
res []response.AppParam
|
||||||
appForm dto.AppForm
|
appForm dto.AppForm
|
||||||
@@ -459,14 +486,20 @@ func (a AppInstallService) GetParams(id uint) ([]response.AppParam, error) {
|
|||||||
}
|
}
|
||||||
appParam.LabelZh = form.LabelZh
|
appParam.LabelZh = form.LabelZh
|
||||||
appParam.LabelEn = form.LabelEn
|
appParam.LabelEn = form.LabelEn
|
||||||
|
appParam.Value = v
|
||||||
if form.Type == "service" {
|
if form.Type == "service" {
|
||||||
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithServiceName(v.(string)))
|
appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithServiceName(v.(string)))
|
||||||
appParam.Value = appInstall.Name
|
appParam.ShowValue = appInstall.Name
|
||||||
res = append(res, appParam)
|
} else if form.Type == "select" {
|
||||||
} else {
|
for _, fv := range form.Values {
|
||||||
appParam.Value = v
|
if fv.Value == v {
|
||||||
res = append(res, appParam)
|
appParam.ShowValue = fv.Label
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appParam.Values = form.Values
|
||||||
}
|
}
|
||||||
|
res = append(res, appParam)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
@@ -622,7 +655,7 @@ func updateInstallInfoInDB(appKey, appName, param string, isRestart bool, value
|
|||||||
}, commonRepo.WithByID(appInstall.ID))
|
}, commonRepo.WithByID(appInstall.ID))
|
||||||
}
|
}
|
||||||
if param == "user-password" {
|
if param == "user-password" {
|
||||||
oldVal = fmt.Sprintf("\"PANEL_DB_USER_PASSWORD\":\"%v\"", appInstall.Password)
|
oldVal = fmt.Sprintf("\"PANEL_DB_USER_PASSWORD\":\"%v\"", appInstall.UserPassword)
|
||||||
newVal = fmt.Sprintf("\"PANEL_DB_USER_PASSWORD\":\"%v\"", value)
|
newVal = fmt.Sprintf("\"PANEL_DB_USER_PASSWORD\":\"%v\"", value)
|
||||||
_ = appInstallRepo.BatchUpdateBy(map[string]interface{}{
|
_ = appInstallRepo.BatchUpdateBy(map[string]interface{}{
|
||||||
"param": strings.ReplaceAll(appInstall.Param, oldVal, newVal),
|
"param": strings.ReplaceAll(appInstall.Param, oldVal, newVal),
|
||||||
|
@@ -86,9 +86,9 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin) (*dto.UserLogi
|
|||||||
}
|
}
|
||||||
pass, err := encrypt.StringDecrypt(passwrodSetting.Value)
|
pass, err := encrypt.StringDecrypt(passwrodSetting.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, constant.ErrAuth
|
return nil, err
|
||||||
}
|
}
|
||||||
if info.Password != pass && nameSetting.Value != info.Name {
|
if info.Password != pass || nameSetting.Value != info.Name {
|
||||||
return nil, constant.ErrAuth
|
return nil, constant.ErrAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -134,7 +134,7 @@ func (u *BackupService) DownloadRecord(info dto.DownloadRecord) (string, error)
|
|||||||
tempPath := fmt.Sprintf("%sdownload%s", constant.DataDir, info.FileDir)
|
tempPath := fmt.Sprintf("%sdownload%s", constant.DataDir, info.FileDir)
|
||||||
if _, err := os.Stat(tempPath); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(tempPath); err != nil && os.IsNotExist(err) {
|
||||||
if err = os.MkdirAll(tempPath, os.ModePerm); err != nil {
|
if err = os.MkdirAll(tempPath, os.ModePerm); err != nil {
|
||||||
fmt.Println(err)
|
global.LOG.Errorf("mkdir %s failed, err: %v", tempPath, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
targetPath := tempPath + info.FileName
|
targetPath := tempPath + info.FileName
|
||||||
|
@@ -181,16 +181,19 @@ func handleAppRecover(install *model.AppInstall, recoverFile string, isRollback
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := handleMysqlRecover(mysqlInfo, tmpPath, db.Name, fmt.Sprintf("%s.sql.gz", install.Name), true); err != nil {
|
if err := handleMysqlRecover(mysqlInfo, tmpPath, db.Name, fmt.Sprintf("%s.sql.gz", install.Name), true); err != nil {
|
||||||
|
global.LOG.Errorf("handle recover from sql.gz failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := handleUnTar(tmpPath+"/app.tar.gz", fmt.Sprintf("%s/%s", constant.AppInstallDir, install.App.Key)); err != nil {
|
if err := handleUnTar(tmpPath+"/app.tar.gz", fmt.Sprintf("%s/%s", constant.AppInstallDir, install.App.Key)); err != nil {
|
||||||
|
global.LOG.Errorf("handle recover from app.tar.gz failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
oldInstall.Status = constant.Running
|
oldInstall.Status = constant.Running
|
||||||
if err := appInstallRepo.Save(install); err != nil {
|
if err := appInstallRepo.Save(install); err != nil {
|
||||||
|
global.LOG.Errorf("save db app install failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
isOk = true
|
isOk = true
|
||||||
|
@@ -106,8 +106,8 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
|||||||
return fmt.Errorf("backup website %s for rollback before recover failed, err: %v", website.Alias, err)
|
return fmt.Errorf("backup website %s for rollback before recover failed, err: %v", website.Alias, err)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
global.LOG.Info("recover failed, start to rollback now")
|
|
||||||
if !isOk {
|
if !isOk {
|
||||||
|
global.LOG.Info("recover failed, start to rollback now")
|
||||||
if err := handleWebsiteRecover(website, rollbackFile, true); err != nil {
|
if err := handleWebsiteRecover(website, rollbackFile, true); err != nil {
|
||||||
global.LOG.Errorf("rollback website %s from %s failed, err: %v", website.Alias, rollbackFile, err)
|
global.LOG.Errorf("rollback website %s from %s failed, err: %v", website.Alias, rollbackFile, err)
|
||||||
return
|
return
|
||||||
@@ -126,6 +126,7 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
|||||||
}
|
}
|
||||||
nginxConfPath := fmt.Sprintf("%s/openresty/%s/conf/conf.d", constant.AppInstallDir, nginxInfo.Name)
|
nginxConfPath := fmt.Sprintf("%s/openresty/%s/conf/conf.d", constant.AppInstallDir, nginxInfo.Name)
|
||||||
if err := fileOp.CopyFile(fmt.Sprintf("%s/%s.conf", tmpPath, website.Alias), nginxConfPath); err != nil {
|
if err := fileOp.CopyFile(fmt.Sprintf("%s/%s.conf", tmpPath, website.Alias), nginxConfPath); err != nil {
|
||||||
|
global.LOG.Errorf("handle recover from conf.d failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,22 +136,27 @@ func handleWebsiteRecover(website *model.Website, recoverFile string, isRollback
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := handleAppRecover(&app, fmt.Sprintf("%s/%s.app.tar.gz", tmpPath, website.Alias), true); err != nil {
|
if err := handleAppRecover(&app, fmt.Sprintf("%s/%s.app.tar.gz", tmpPath, website.Alias), true); err != nil {
|
||||||
|
global.LOG.Errorf("handle recover from app.tar.gz failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, app.App.Key, app.Name)); err != nil {
|
if _, err := compose.Restart(fmt.Sprintf("%s/%s/%s/docker-compose.yml", constant.AppInstallDir, app.App.Key, app.Name)); err != nil {
|
||||||
|
global.LOG.Errorf("docker-compose restart failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
siteDir := fmt.Sprintf("%s/openresty/%s/www/sites", constant.AppInstallDir, nginxInfo.Name)
|
siteDir := fmt.Sprintf("%s/openresty/%s/www/sites", constant.AppInstallDir, nginxInfo.Name)
|
||||||
if err := handleUnTar(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), siteDir); err != nil {
|
if err := handleUnTar(fmt.Sprintf("%s/%s.web.tar.gz", tmpPath, website.Alias), siteDir); err != nil {
|
||||||
|
global.LOG.Errorf("handle recover from web.tar.gz failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
stdout, err := cmd.Execf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName)
|
stdout, err := cmd.Execf("docker exec -i %s nginx -s reload", nginxInfo.ContainerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
global.LOG.Errorf("nginx -s reload failed, err: %s", stdout)
|
||||||
return errors.New(string(stdout))
|
return errors.New(string(stdout))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := websiteRepo.SaveWithoutCtx(&oldWebsite); err != nil {
|
if err := websiteRepo.SaveWithoutCtx(&oldWebsite); err != nil {
|
||||||
|
global.LOG.Errorf("handle save website data failed, err: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
isOk = true
|
isOk = true
|
||||||
|
@@ -3,6 +3,7 @@ package service
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -33,7 +34,7 @@ type IContainerService interface {
|
|||||||
PageVolume(req dto.SearchWithPage) (int64, interface{}, error)
|
PageVolume(req dto.SearchWithPage) (int64, interface{}, error)
|
||||||
ListVolume() ([]dto.Options, error)
|
ListVolume() ([]dto.Options, error)
|
||||||
PageCompose(req dto.SearchWithPage) (int64, interface{}, error)
|
PageCompose(req dto.SearchWithPage) (int64, interface{}, error)
|
||||||
CreateCompose(req dto.ComposeCreate) error
|
CreateCompose(req dto.ComposeCreate) (string, error)
|
||||||
ComposeOperation(req dto.ComposeOperation) error
|
ComposeOperation(req dto.ComposeOperation) error
|
||||||
ContainerCreate(req dto.ContainerCreate) error
|
ContainerCreate(req dto.ContainerCreate) error
|
||||||
ContainerOperation(req dto.ContainerOperation) error
|
ContainerOperation(req dto.ContainerOperation) error
|
||||||
@@ -98,6 +99,10 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
|||||||
if _, ok := container.Labels[composeProjectLabel]; ok {
|
if _, ok := container.Labels[composeProjectLabel]; ok {
|
||||||
IsFromCompose = true
|
IsFromCompose = true
|
||||||
}
|
}
|
||||||
|
IsFromApp := false
|
||||||
|
if created, ok := container.Labels[composeCreatedBy]; ok && created == "Apps" {
|
||||||
|
IsFromApp = true
|
||||||
|
}
|
||||||
backDatas = append(backDatas, dto.ContainerInfo{
|
backDatas = append(backDatas, dto.ContainerInfo{
|
||||||
ContainerID: container.ID,
|
ContainerID: container.ID,
|
||||||
CreateTime: time.Unix(container.Created, 0).Format("2006-01-02 15:04:05"),
|
CreateTime: time.Unix(container.Created, 0).Format("2006-01-02 15:04:05"),
|
||||||
@@ -106,6 +111,7 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
|||||||
ImageName: container.Image,
|
ImageName: container.Image,
|
||||||
State: container.State,
|
State: container.State,
|
||||||
RunTime: container.Status,
|
RunTime: container.Status,
|
||||||
|
IsFromApp: IsFromApp,
|
||||||
IsFromCompose: IsFromCompose,
|
IsFromCompose: IsFromCompose,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -234,7 +240,7 @@ func (u *ContainerService) ContainerLogs(req dto.ContainerLog) (string, error) {
|
|||||||
}
|
}
|
||||||
stdout, err := cmd.CombinedOutput()
|
stdout, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.New(string(stdout))
|
||||||
}
|
}
|
||||||
return string(stdout), nil
|
return string(stdout), nil
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,8 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -123,41 +125,49 @@ func (u *ContainerService) PageCompose(req dto.SearchWithPage) (int64, interface
|
|||||||
return int64(total), BackDatas, nil
|
return int64(total), BackDatas, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ContainerService) CreateCompose(req dto.ComposeCreate) error {
|
func (u *ContainerService) TestCompose(req dto.ComposeCreate) (bool, error) {
|
||||||
if req.From == "template" {
|
if err := u.loadPath(&req); err != nil {
|
||||||
template, err := composeRepo.Get(commonRepo.WithByID(req.Template))
|
return false, err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.From = "edit"
|
|
||||||
req.File = template.Content
|
|
||||||
}
|
}
|
||||||
if req.From == "edit" {
|
cmd := exec.Command("docker-compose", "-f", req.Path, "config")
|
||||||
dir := fmt.Sprintf("%s/docker/compose/%s", constant.DataDir, req.Name)
|
stdout, err := cmd.CombinedOutput()
|
||||||
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
if err != nil {
|
||||||
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
|
return false, errors.New(string(stdout))
|
||||||
return err
|
}
|
||||||
}
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
path := fmt.Sprintf("%s/docker-compose.yml", dir)
|
func (u *ContainerService) CreateCompose(req dto.ComposeCreate) (string, error) {
|
||||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
if err := u.loadPath(&req); err != nil {
|
||||||
if err != nil {
|
return "", err
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
write := bufio.NewWriter(file)
|
|
||||||
_, _ = write.WriteString(string(req.File))
|
|
||||||
write.Flush()
|
|
||||||
req.Path = path
|
|
||||||
}
|
}
|
||||||
global.LOG.Infof("docker-compose.yml %s create successful, start to docker-compose up", req.Name)
|
global.LOG.Infof("docker-compose.yml %s create successful, start to docker-compose up", req.Name)
|
||||||
if stdout, err := compose.Up(req.Path); err != nil {
|
|
||||||
return errors.New(string(stdout))
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = composeRepo.CreateRecord(&model.Compose{Name: req.Name})
|
if req.From == "path" {
|
||||||
return nil
|
req.Name = path.Base(strings.ReplaceAll(req.Path, "/"+path.Base(req.Path), ""))
|
||||||
|
}
|
||||||
|
logName := path.Dir(req.Path) + "/compose.log"
|
||||||
|
file, err := os.OpenFile(logName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
defer file.Close()
|
||||||
|
cmd := exec.Command("docker-compose", "-f", req.Path, "up", "-d")
|
||||||
|
stdout, err := cmd.CombinedOutput()
|
||||||
|
_, _ = file.Write(stdout)
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("docker-compose up %s failed, err: %v", req.Name, err)
|
||||||
|
_, _ = compose.Down(req.Path)
|
||||||
|
_, _ = file.WriteString("docker-compose up failed!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
global.LOG.Infof("docker-compose up %s successful!", req.Name)
|
||||||
|
_ = composeRepo.CreateRecord(&model.Compose{Name: req.Name})
|
||||||
|
_, _ = file.WriteString("docker-compose up successful!")
|
||||||
|
}()
|
||||||
|
|
||||||
|
return logName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
func (u *ContainerService) ComposeOperation(req dto.ComposeOperation) error {
|
||||||
@@ -199,3 +209,34 @@ func (u *ContainerService) ComposeUpdate(req dto.ComposeUpdate) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *ContainerService) loadPath(req *dto.ComposeCreate) error {
|
||||||
|
if req.From == "template" {
|
||||||
|
template, err := composeRepo.Get(commonRepo.WithByID(req.Template))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.From = "edit"
|
||||||
|
req.File = template.Content
|
||||||
|
}
|
||||||
|
if req.From == "edit" {
|
||||||
|
dir := fmt.Sprintf("%s/docker/compose/%s", constant.DataDir, req.Name)
|
||||||
|
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
||||||
|
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path := fmt.Sprintf("%s/docker-compose.yml", dir)
|
||||||
|
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
write := bufio.NewWriter(file)
|
||||||
|
_, _ = write.WriteString(string(req.File))
|
||||||
|
write.Flush()
|
||||||
|
req.Path = path
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -7,6 +7,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/network"
|
"github.com/docker/docker/api/types/network"
|
||||||
@@ -80,6 +82,9 @@ func (u *ContainerService) DeleteNetwork(req dto.BatchDelete) error {
|
|||||||
}
|
}
|
||||||
for _, id := range req.Names {
|
for _, id := range req.Names {
|
||||||
if err := client.NetworkRemove(context.TODO(), id); err != nil {
|
if err := client.NetworkRemove(context.TODO(), id); err != nil {
|
||||||
|
if strings.Contains(err.Error(), "has active endpoints") {
|
||||||
|
return buserr.WithDetail(constant.ErrInUsed, id, nil)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,12 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
@@ -96,6 +96,9 @@ func (u *ContainerService) DeleteVolume(req dto.BatchDelete) error {
|
|||||||
}
|
}
|
||||||
for _, id := range req.Names {
|
for _, id := range req.Names {
|
||||||
if err := client.VolumeRemove(context.TODO(), id, true); err != nil {
|
if err := client.VolumeRemove(context.TODO(), id, true); err != nil {
|
||||||
|
if strings.Contains(err.Error(), "volume is in use") {
|
||||||
|
return buserr.WithDetail(constant.ErrInUsed, id, nil)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,12 +125,8 @@ func (u *ContainerService) CreateVolume(req dto.VolumeCreat) error {
|
|||||||
DriverOpts: stringsToMap(req.Options),
|
DriverOpts: stringsToMap(req.Options),
|
||||||
Labels: stringsToMap(req.Labels),
|
Labels: stringsToMap(req.Labels),
|
||||||
}
|
}
|
||||||
stat, err := client.VolumeCreate(context.TODO(), options)
|
if _, err := client.VolumeCreate(context.TODO(), options); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// if len(stat.CreatedAt) != 0 {
|
|
||||||
fmt.Println(stat)
|
|
||||||
// }
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -2,17 +2,14 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/cloud_storage"
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/robfig/cron/v3"
|
"github.com/robfig/cron/v3"
|
||||||
@@ -92,69 +89,28 @@ func (u *CronjobService) Download(down dto.CronjobDownload) (string, error) {
|
|||||||
if cronjob.ID == 0 {
|
if cronjob.ID == 0 {
|
||||||
return "", constant.ErrRecordNotFound
|
return "", constant.ErrRecordNotFound
|
||||||
}
|
}
|
||||||
|
if backup.Type == "LOCAL" {
|
||||||
global.LOG.Infof("start to download records %s from %s", cronjob.Type, backup.Type)
|
if _, err := os.Stat(record.File); err != nil && os.IsNotExist(err) {
|
||||||
varMap := make(map[string]interface{})
|
return "", constant.ErrRecordNotFound
|
||||||
if err := json.Unmarshal([]byte(backup.Vars), &varMap); err != nil {
|
}
|
||||||
|
return record.File, nil
|
||||||
|
}
|
||||||
|
if record.FromLocal {
|
||||||
|
local, _ := loadLocalDir()
|
||||||
|
if _, err := os.Stat(local + "/" + record.File); err == nil {
|
||||||
|
return local + "/" + record.File, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
client, err := NewIBackupService().NewClient(&backup)
|
||||||
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
varMap["type"] = backup.Type
|
tempPath := fmt.Sprintf("%s/download/%s", constant.DataDir, record.File)
|
||||||
if backup.Type != "LOCAL" {
|
isOK, _ := client.Download(record.File, tempPath)
|
||||||
varMap["bucket"] = backup.Bucket
|
if !isOK || err != nil {
|
||||||
switch backup.Type {
|
return "", constant.ErrRecordNotFound
|
||||||
case constant.Sftp:
|
|
||||||
varMap["username"] = backup.AccessKey
|
|
||||||
varMap["password"] = backup.Credential
|
|
||||||
case constant.OSS, constant.S3, constant.MinIo:
|
|
||||||
varMap["accessKey"] = backup.AccessKey
|
|
||||||
varMap["secretKey"] = backup.Credential
|
|
||||||
}
|
|
||||||
backClient, err := cloud_storage.NewCloudStorageClient(varMap)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("new cloud storage client failed, err: %v", err)
|
|
||||||
}
|
|
||||||
global.LOG.Info("new backup client successful")
|
|
||||||
commonDir := fmt.Sprintf("%s/%s/", cronjob.Type, cronjob.Name)
|
|
||||||
name := fmt.Sprintf("%s%s.tar.gz", commonDir, record.StartTime.Format("20060102150405"))
|
|
||||||
if cronjob.Type == "database" {
|
|
||||||
name = fmt.Sprintf("%s%s.gz", commonDir, record.StartTime.Format("20060102150405"))
|
|
||||||
}
|
|
||||||
tempPath := fmt.Sprintf("%s/download/%s", constant.DataDir, commonDir)
|
|
||||||
if _, err := os.Stat(tempPath); err != nil && os.IsNotExist(err) {
|
|
||||||
if err = os.MkdirAll(tempPath, os.ModePerm); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
global.LOG.Infof("download records %s from %s to %s", name, commonDir, tempPath)
|
|
||||||
targetPath := tempPath + strings.ReplaceAll(name, commonDir, "")
|
|
||||||
if _, err = os.Stat(targetPath); err != nil && os.IsNotExist(err) {
|
|
||||||
isOK, err := backClient.Download(name, targetPath)
|
|
||||||
if !isOK {
|
|
||||||
return "", fmt.Errorf("cloud storage download failed, err: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return targetPath, nil
|
|
||||||
}
|
|
||||||
if _, ok := varMap["dir"]; !ok {
|
|
||||||
return "", errors.New("load local backup dir failed")
|
|
||||||
}
|
|
||||||
global.LOG.Infof("record is save in local dir %s", varMap["dir"])
|
|
||||||
|
|
||||||
switch cronjob.Type {
|
|
||||||
case "website":
|
|
||||||
return fmt.Sprintf("%v/website/%s/website_%s_%s.tar.gz", varMap["dir"], cronjob.Website, cronjob.Website, record.StartTime.Format("20060102150405")), nil
|
|
||||||
case "database":
|
|
||||||
mysqlInfo, err := appInstallRepo.LoadBaseInfo("mysql", "")
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("load mysqlInfo failed, err: %v", err)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%v/database/mysql/%s/%s/db_%s_%s.sql.gz", varMap["dir"], mysqlInfo.Name, cronjob.DBName, cronjob.DBName, record.StartTime.Format("20060102150405")), nil
|
|
||||||
case "directory":
|
|
||||||
return fmt.Sprintf("%v/%s/%s/directory%s_%s.tar.gz", varMap["dir"], cronjob.Type, cronjob.Name, strings.ReplaceAll(cronjob.SourceDir, "/", "_"), record.StartTime.Format("20060102150405")), nil
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("not support type %s", cronjob.Type)
|
|
||||||
}
|
}
|
||||||
|
return tempPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *CronjobService) HandleOnce(id uint) error {
|
func (u *CronjobService) HandleOnce(id uint) error {
|
||||||
|
@@ -22,8 +22,7 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
|||||||
message []byte
|
message []byte
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
record := cronjobRepo.StartRecords(cronjob.ID, "")
|
record := cronjobRepo.StartRecords(cronjob.ID, cronjob.KeepLocal, "")
|
||||||
record.FromLocal = cronjob.KeepLocal
|
|
||||||
go func() {
|
go func() {
|
||||||
switch cronjob.Type {
|
switch cronjob.Type {
|
||||||
case "shell":
|
case "shell":
|
||||||
@@ -118,6 +117,8 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemFileDir := strings.ReplaceAll(backupDir, localDir+"/", "")
|
||||||
if len(record.Name) != 0 {
|
if len(record.Name) != 0 {
|
||||||
record.FileName = fileName
|
record.FileName = fileName
|
||||||
record.FileDir = backupDir
|
record.FileDir = backupDir
|
||||||
@@ -125,7 +126,7 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
|||||||
record.BackupType = backup.Type
|
record.BackupType = backup.Type
|
||||||
if !cronjob.KeepLocal && backup.Type != "LOCAL" {
|
if !cronjob.KeepLocal && backup.Type != "LOCAL" {
|
||||||
record.Source = backup.Type
|
record.Source = backup.Type
|
||||||
record.FileDir = strings.ReplaceAll(backupDir, localDir+"/", "")
|
record.FileDir = itemFileDir
|
||||||
}
|
}
|
||||||
if err := backupRepo.CreateRecord(&record); err != nil {
|
if err := backupRepo.CreateRecord(&record); err != nil {
|
||||||
global.LOG.Errorf("save backup record failed, err: %v", err)
|
global.LOG.Errorf("save backup record failed, err: %v", err)
|
||||||
@@ -133,7 +134,10 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fullPath := fmt.Sprintf("%s/%s", record.FileDir, fileName)
|
fullPath := fmt.Sprintf("%s/%s", backupDir, fileName)
|
||||||
|
if backup.Type != "LOCAL" {
|
||||||
|
fullPath = fmt.Sprintf("%s/%s", itemFileDir, fileName)
|
||||||
|
}
|
||||||
if backup.Type == "LOCAL" {
|
if backup.Type == "LOCAL" {
|
||||||
u.HandleRmExpired(backup.Type, backupDir, cronjob, nil)
|
u.HandleRmExpired(backup.Type, backupDir, cronjob, nil)
|
||||||
return fullPath, nil
|
return fullPath, nil
|
||||||
@@ -148,10 +152,13 @@ func (u *CronjobService) HandleBackup(cronjob *model.Cronjob, startTime time.Tim
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fullPath, err
|
return fullPath, err
|
||||||
}
|
}
|
||||||
if _, err = client.Upload(backupDir+"/"+fileName, fullPath); err != nil {
|
if _, err = client.Upload(backupDir+"/"+fileName, itemFileDir+"/"+fileName); err != nil {
|
||||||
return fullPath, err
|
return fullPath, err
|
||||||
}
|
}
|
||||||
u.HandleRmExpired(backup.Type, backupDir, cronjob, client)
|
u.HandleRmExpired(backup.Type, itemFileDir, cronjob, client)
|
||||||
|
if cronjob.KeepLocal {
|
||||||
|
u.HandleRmExpired("LOCAL", backupDir, cronjob, client)
|
||||||
|
}
|
||||||
return fullPath, nil
|
return fullPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,9 +192,7 @@ func (u *CronjobService) HandleRmExpired(backType, backupDir string, cronjob *mo
|
|||||||
for i := 0; i < len(currentObjs)-int(cronjob.RetainCopies); i++ {
|
for i := 0; i < len(currentObjs)-int(cronjob.RetainCopies); i++ {
|
||||||
_, _ = backClient.Delete(currentObjs[i].(string))
|
_, _ = backClient.Delete(currentObjs[i].(string))
|
||||||
}
|
}
|
||||||
if !cronjob.KeepLocal {
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
files, err := ioutil.ReadDir(backupDir)
|
files, err := ioutil.ReadDir(backupDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -292,7 +292,7 @@ func (u *MysqlService) ChangeAccess(info dto.ChangeDBInfo) error {
|
|||||||
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("create user if not exists '%s'@'%s' identified by '%s';", mysql.Username, info.Value, mysql.Password)); err != nil {
|
if err := excuteSql(app.ContainerName, app.Password, fmt.Sprintf("create user if not exists '%s'@'%s' identified by '%s';", mysql.Username, info.Value, mysql.Password)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
grantStr := fmt.Sprintf("grant all privileges on %s.* to '%s'@'%s'", mysql.Name, mysql.Username, info.Value)
|
grantStr := fmt.Sprintf("grant all privileges on `%s`.* to '%s'@'%s'", mysql.Name, mysql.Username, info.Value)
|
||||||
if app.Version == "5.7.39" {
|
if app.Version == "5.7.39" {
|
||||||
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, mysql.Password)
|
grantStr = fmt.Sprintf("%s identified by '%s' with grant option;", grantStr, mysql.Password)
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,6 @@ type ServiceGroup struct {
|
|||||||
SettingService
|
SettingService
|
||||||
BackupService
|
BackupService
|
||||||
|
|
||||||
WebsiteGroupService
|
|
||||||
WebsiteService
|
WebsiteService
|
||||||
WebsiteDnsAccountService
|
WebsiteDnsAccountService
|
||||||
WebsiteSSLService
|
WebsiteSSLService
|
||||||
@@ -68,7 +67,6 @@ var (
|
|||||||
backupRepo = repo.RepoGroupApp.BackupRepo
|
backupRepo = repo.RepoGroupApp.BackupRepo
|
||||||
|
|
||||||
websiteRepo = repo.NewIWebsiteRepo()
|
websiteRepo = repo.NewIWebsiteRepo()
|
||||||
websiteGroupRepo = repo.RepoGroupApp.WebsiteGroupRepo
|
|
||||||
websiteDomainRepo = repo.RepoGroupApp.WebsiteDomainRepo
|
websiteDomainRepo = repo.RepoGroupApp.WebsiteDomainRepo
|
||||||
websiteDnsRepo = repo.RepoGroupApp.WebsiteDnsAccountRepo
|
websiteDnsRepo = repo.RepoGroupApp.WebsiteDnsAccountRepo
|
||||||
websiteSSLRepo = repo.NewISSLRepo()
|
websiteSSLRepo = repo.NewISSLRepo()
|
||||||
|
@@ -22,7 +22,7 @@ func NewIGroupService() IGroupService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *GroupService) List(req dto.GroupSearch) ([]dto.GroupInfo, error) {
|
func (u *GroupService) List(req dto.GroupSearch) ([]dto.GroupInfo, error) {
|
||||||
groups, err := groupRepo.GetList(commonRepo.WithByType(req.Type))
|
groups, err := groupRepo.GetList(commonRepo.WithByType(req.Type), commonRepo.WithOrderBy("is_default desc"), commonRepo.WithOrderBy("created_at desc"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, constant.ErrRecordNotFound
|
return nil, constant.ErrRecordNotFound
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ func (u *GroupService) List(req dto.GroupSearch) ([]dto.GroupInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (u *GroupService) Create(req dto.GroupCreate) error {
|
func (u *GroupService) Create(req dto.GroupCreate) error {
|
||||||
group, _ := groupRepo.Get(commonRepo.WithByName(req.Name), commonRepo.WithByName(req.Name))
|
group, _ := groupRepo.Get(commonRepo.WithByName(req.Name), commonRepo.WithByType(req.Type))
|
||||||
if group.ID != 0 {
|
if group.ID != 0 {
|
||||||
return constant.ErrRecordExist
|
return constant.ErrRecordExist
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ func (u *GroupService) Delete(id uint) error {
|
|||||||
}
|
}
|
||||||
switch group.Type {
|
switch group.Type {
|
||||||
case "website":
|
case "website":
|
||||||
websites, _ := websiteRepo.GetBy(commonRepo.WithByGroupID(id))
|
websites, _ := websiteRepo.GetBy(websiteRepo.WithGroupID(id))
|
||||||
if len(websites) > 0 {
|
if len(websites) > 0 {
|
||||||
return buserr.New(constant.ErrGroupIsUsed)
|
return buserr.New(constant.ErrGroupIsUsed)
|
||||||
}
|
}
|
||||||
@@ -73,7 +73,7 @@ func (u *GroupService) Delete(id uint) error {
|
|||||||
|
|
||||||
func (u *GroupService) Update(req dto.GroupUpdate) error {
|
func (u *GroupService) Update(req dto.GroupUpdate) error {
|
||||||
if req.IsDefault {
|
if req.IsDefault {
|
||||||
if err := groupRepo.CancelDefault(); err != nil {
|
if err := groupRepo.CancelDefault(req.Type); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||||
@@ -53,8 +54,8 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error)
|
|||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
if len(req.Info) != 0 {
|
if len(req.Info) != 0 {
|
||||||
lenth, count := len(list), 0
|
length, count := len(list), 0
|
||||||
for count < lenth {
|
for count < length {
|
||||||
hasTag := false
|
hasTag := false
|
||||||
for _, tag := range list[count].RepoTags {
|
for _, tag := range list[count].RepoTags {
|
||||||
if strings.Contains(tag, req.Info) {
|
if strings.Contains(tag, req.Info) {
|
||||||
@@ -64,7 +65,7 @@ func (u *ImageService) Page(req dto.SearchWithPage) (int64, interface{}, error)
|
|||||||
}
|
}
|
||||||
if !hasTag {
|
if !hasTag {
|
||||||
list = append(list[:count], list[(count+1):]...)
|
list = append(list[:count], list[(count+1):]...)
|
||||||
lenth--
|
length--
|
||||||
} else {
|
} else {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
@@ -121,6 +122,7 @@ func (u *ImageService) ImageBuild(req dto.ImageBuild) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
fileName := "Dockerfile"
|
||||||
if req.From == "edit" {
|
if req.From == "edit" {
|
||||||
dir := fmt.Sprintf("%s/docker/build/%s", constant.DataDir, strings.ReplaceAll(req.Name, ":", "_"))
|
dir := fmt.Sprintf("%s/docker/build/%s", constant.DataDir, strings.ReplaceAll(req.Name, ":", "_"))
|
||||||
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
||||||
@@ -140,7 +142,8 @@ func (u *ImageService) ImageBuild(req dto.ImageBuild) (string, error) {
|
|||||||
write.Flush()
|
write.Flush()
|
||||||
req.Dockerfile = dir
|
req.Dockerfile = dir
|
||||||
} else {
|
} else {
|
||||||
req.Dockerfile = strings.ReplaceAll(req.Dockerfile, "/Dockerfile", "")
|
fileName = path.Base(req.Dockerfile)
|
||||||
|
req.Dockerfile = path.Dir(req.Dockerfile)
|
||||||
}
|
}
|
||||||
tar, err := archive.TarWithOptions(req.Dockerfile+"/", &archive.TarOptions{})
|
tar, err := archive.TarWithOptions(req.Dockerfile+"/", &archive.TarOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -148,7 +151,7 @@ func (u *ImageService) ImageBuild(req dto.ImageBuild) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
opts := types.ImageBuildOptions{
|
opts := types.ImageBuildOptions{
|
||||||
Dockerfile: "Dockerfile",
|
Dockerfile: fileName,
|
||||||
Tags: []string{req.Name},
|
Tags: []string{req.Name},
|
||||||
Remove: true,
|
Remove: true,
|
||||||
Labels: stringsToMap(req.Tags),
|
Labels: stringsToMap(req.Tags),
|
||||||
@@ -178,14 +181,14 @@ func (u *ImageService) ImageBuild(req dto.ImageBuild) (string, error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(string(body), "error") && strings.Contains(string(body), "failed:") {
|
if strings.Contains(string(body), "errorDetail") || strings.Contains(string(body), "error:") {
|
||||||
global.LOG.Errorf("build image %s failed", req.Name)
|
global.LOG.Errorf("build image %s failed", req.Name)
|
||||||
_, _ = file.Write(body)
|
_, _ = file.Write(body)
|
||||||
_, _ = file.WriteString("image build failed!")
|
_, _ = file.WriteString("image build failed!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Infof("build image %s successful!", req.Name)
|
global.LOG.Infof("build image %s successful!", req.Name)
|
||||||
_, _ = io.Copy(file, res.Body)
|
_, _ = file.Write(body)
|
||||||
_, _ = file.WriteString("image build successful!")
|
_, _ = file.WriteString("image build successful!")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -378,8 +381,14 @@ func (u *ImageService) ImageRemove(req dto.BatchDelete) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, ids := range req.Names {
|
for _, id := range req.Names {
|
||||||
if _, err := client.ImageRemove(context.TODO(), ids, types.ImageRemoveOptions{Force: true, PruneChildren: true}); err != nil {
|
if _, err := client.ImageRemove(context.TODO(), id, types.ImageRemoveOptions{Force: true, PruneChildren: true}); err != nil {
|
||||||
|
if strings.Contains(err.Error(), "image is being used") {
|
||||||
|
if strings.Contains(id, "sha256:") {
|
||||||
|
return buserr.New(constant.ErrObjectInUsed)
|
||||||
|
}
|
||||||
|
return buserr.WithDetail(constant.ErrInUsed, id, nil)
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,12 +4,15 @@ import (
|
|||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LogService struct{}
|
type LogService struct{}
|
||||||
|
|
||||||
|
const logs = "https://resource.fit2cloud.com/installation-log.sh"
|
||||||
|
|
||||||
type ILogService interface {
|
type ILogService interface {
|
||||||
CreateLoginLog(operation model.LoginLog) error
|
CreateLoginLog(operation model.LoginLog) error
|
||||||
PageLoginLog(search dto.SearchLgLogWithPage) (int64, interface{}, error)
|
PageLoginLog(search dto.SearchLgLogWithPage) (int64, interface{}, error)
|
||||||
@@ -77,3 +80,7 @@ func (u *LogService) CleanLogs(logtype string) error {
|
|||||||
}
|
}
|
||||||
return logRepo.CleanLogin()
|
return logRepo.CleanLogin()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func writeLogs(version string) {
|
||||||
|
_, _ = cmd.Execf("curl -sfL %s | sh -s 1p upgrade %s", logs, version)
|
||||||
|
}
|
||||||
|
@@ -66,6 +66,9 @@ func (u *SnapshotService) SnapshotImport(req dto.SnapshotImport) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("incorrect snapshot name format of %s", snap)
|
return fmt.Errorf("incorrect snapshot name format of %s", snap)
|
||||||
}
|
}
|
||||||
|
if strings.HasSuffix(snap, ".tar.gz") {
|
||||||
|
snap = strings.ReplaceAll(snap, ".tar.gz", "")
|
||||||
|
}
|
||||||
itemSnap := model.Snapshot{
|
itemSnap := model.Snapshot{
|
||||||
Name: snap,
|
Name: snap,
|
||||||
From: req.From,
|
From: req.From,
|
||||||
|
@@ -1,18 +1,20 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/common"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ type UpgradeService struct{}
|
|||||||
|
|
||||||
type IUpgradeService interface {
|
type IUpgradeService interface {
|
||||||
Upgrade(req dto.Upgrade) error
|
Upgrade(req dto.Upgrade) error
|
||||||
|
LoadNotes(req dto.Upgrade) (string, error)
|
||||||
SearchUpgrade() (*dto.UpgradeInfo, error)
|
SearchUpgrade() (*dto.UpgradeInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,36 +37,50 @@ func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
versionRes, err := http.Get(fmt.Sprintf("%s/%s/latest", global.CONF.System.RepoUrl, global.CONF.System.Mode))
|
latestVersion, err := u.loadVersion(true, currentVersion.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
global.LOG.Infof("load latest version failed, err: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer versionRes.Body.Close()
|
if !common.CompareVersion(string(latestVersion), currentVersion.Value) {
|
||||||
version, err := ioutil.ReadAll(versionRes.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
isNew, err := compareVersion(currentVersion.Value, string(version))
|
upgrade.LatestVersion = latestVersion
|
||||||
if !isNew || err != nil {
|
if latestVersion[0:4] == currentVersion.Value[0:4] {
|
||||||
return nil, err
|
upgrade.NewVersion = ""
|
||||||
|
} else {
|
||||||
|
newerVersion, err := u.loadVersion(false, currentVersion.Value)
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Infof("load newer version failed, err: %v", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if newerVersion == currentVersion.Value {
|
||||||
|
upgrade.NewVersion = ""
|
||||||
|
} else {
|
||||||
|
upgrade.NewVersion = newerVersion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
itemVersion := upgrade.LatestVersion
|
||||||
|
if upgrade.NewVersion != "" {
|
||||||
|
itemVersion = upgrade.NewVersion
|
||||||
|
}
|
||||||
|
notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.System.RepoUrl, global.CONF.System.Mode, itemVersion, itemVersion))
|
||||||
|
|
||||||
upgrade.NewVersion = string(version)
|
|
||||||
|
|
||||||
releaseNotes, err := http.Get(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.System.RepoUrl, global.CONF.System.Mode, upgrade.NewVersion, upgrade.NewVersion))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("load relase-notes of version %s failed, err: %v", latestVersion, err)
|
||||||
}
|
}
|
||||||
defer releaseNotes.Body.Close()
|
upgrade.ReleaseNote = notes
|
||||||
release, err := ioutil.ReadAll(releaseNotes.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
upgrade.ReleaseNote = string(release)
|
|
||||||
|
|
||||||
return &upgrade, nil
|
return &upgrade, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *UpgradeService) LoadNotes(req dto.Upgrade) (string, error) {
|
||||||
|
notes, err := u.loadReleaseNotes(fmt.Sprintf("%s/%s/%s/release/1panel-%s-release-notes", global.CONF.System.RepoUrl, global.CONF.System.Mode, req.Version, req.Version))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("load relase-notes of version %s failed, err: %v", req.Version, err)
|
||||||
|
}
|
||||||
|
return notes, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
|
func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
|
||||||
global.LOG.Info("start to upgrade now...")
|
global.LOG.Info("start to upgrade now...")
|
||||||
fileOp := files.NewFileOp()
|
fileOp := files.NewFileOp()
|
||||||
@@ -128,6 +145,7 @@ func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
global.LOG.Info("upgrade successful!")
|
global.LOG.Info("upgrade successful!")
|
||||||
|
go writeLogs(req.Version)
|
||||||
_ = settingRepo.Update("SystemVersion", req.Version)
|
_ = settingRepo.Update("SystemVersion", req.Version)
|
||||||
_ = settingRepo.Update("SystemStatus", "Free")
|
_ = settingRepo.Update("SystemStatus", "Free")
|
||||||
_, _ = cmd.Exec("systemctl daemon-reload && systemctl restart 1panel.service")
|
_, _ = cmd.Exec("systemctl daemon-reload && systemctl restart 1panel.service")
|
||||||
@@ -173,45 +191,49 @@ func (u *UpgradeService) handleRollback(fileOp files.FileOp, originalDir string,
|
|||||||
if err := cpBinary(originalDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil {
|
if err := cpBinary(originalDir+"/1panel.service", "/etc/systemd/system/1panel.service"); err != nil {
|
||||||
global.LOG.Errorf("rollback 1panel failed, err: %v", err)
|
global.LOG.Errorf("rollback 1panel failed, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareVersion(version, newVersion string) (bool, error) {
|
func (u *UpgradeService) loadVersion(isLatest bool, currentVersion string) (string, error) {
|
||||||
if version == newVersion {
|
path := fmt.Sprintf("%s/%s/latest", global.CONF.System.RepoUrl, global.CONF.System.Mode)
|
||||||
return false, nil
|
if !isLatest {
|
||||||
|
path = fmt.Sprintf("%s/%s/latest.current", global.CONF.System.RepoUrl, global.CONF.System.Mode)
|
||||||
}
|
}
|
||||||
if len(version) == 0 || len(newVersion) == 0 {
|
latestVersionRes, err := http.Get(path)
|
||||||
return false, fmt.Errorf("incorrect version or new version entered %v -- %v", version, newVersion)
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
versions := strings.Split(strings.ReplaceAll(version, "v", ""), ".")
|
defer latestVersionRes.Body.Close()
|
||||||
if len(versions) != 3 {
|
version, err := ioutil.ReadAll(latestVersionRes.Body)
|
||||||
return false, fmt.Errorf("incorrect version input %v", version)
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
newVersions := strings.Split(strings.ReplaceAll(newVersion, "v", ""), ".")
|
if isLatest {
|
||||||
if len(newVersions) != 3 {
|
return string(version), nil
|
||||||
return false, fmt.Errorf("incorrect newVersions input %v", version)
|
|
||||||
}
|
}
|
||||||
version1, _ := strconv.Atoi(versions[0])
|
|
||||||
newVersion1, _ := strconv.Atoi(newVersions[0])
|
versionMap := make(map[string]string)
|
||||||
if newVersion1 > version1 {
|
if err := json.Unmarshal(version, &versionMap); err != nil {
|
||||||
return true, nil
|
return "", fmt.Errorf("load version map failed, err: %v", err)
|
||||||
} else if newVersion1 == version1 {
|
|
||||||
version2, _ := strconv.Atoi(versions[1])
|
|
||||||
newVersion2, _ := strconv.Atoi(newVersions[1])
|
|
||||||
if newVersion2 > version2 {
|
|
||||||
return true, nil
|
|
||||||
} else if newVersion2 == version2 {
|
|
||||||
version3, _ := strconv.Atoi(versions[2])
|
|
||||||
newVersion3, _ := strconv.Atoi(newVersions[2])
|
|
||||||
if newVersion3 > version3 {
|
|
||||||
return true, nil
|
|
||||||
} else {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(currentVersion) < 4 {
|
||||||
|
return "", fmt.Errorf("current version is error format: %s", currentVersion)
|
||||||
|
}
|
||||||
|
if version, ok := versionMap[currentVersion[0:4]]; ok {
|
||||||
|
return version, nil
|
||||||
|
}
|
||||||
|
return "", errors.New("load version failed in latest.current")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UpgradeService) loadReleaseNotes(path string) (string, error) {
|
||||||
|
releaseNotes, err := http.Get(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer releaseNotes.Body.Close()
|
||||||
|
release, err := ioutil.ReadAll(releaseNotes.Body)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(release), nil
|
||||||
}
|
}
|
||||||
|
@@ -1,61 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/model"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/buserr"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
|
||||||
)
|
|
||||||
|
|
||||||
type WebsiteGroupService struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupService) CreateGroup(create request.WebsiteGroupCreate) error {
|
|
||||||
groups, _ := websiteGroupRepo.GetBy(commonRepo.WithByName(create.Name))
|
|
||||||
if len(groups) > 0 {
|
|
||||||
return buserr.New(constant.ErrNameIsExist)
|
|
||||||
}
|
|
||||||
return websiteGroupRepo.Create(&model.WebsiteGroup{
|
|
||||||
Name: create.Name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupService) GetGroups() ([]model.WebsiteGroup, error) {
|
|
||||||
return websiteGroupRepo.GetBy()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupService) UpdateGroup(update request.WebsiteGroupUpdate) error {
|
|
||||||
if update.Default {
|
|
||||||
if err := websiteGroupRepo.CancelDefault(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return websiteGroupRepo.Save(&model.WebsiteGroup{
|
|
||||||
BaseModel: model.BaseModel{
|
|
||||||
ID: update.ID,
|
|
||||||
},
|
|
||||||
Name: update.Name,
|
|
||||||
Default: true,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
exists, _ := websiteGroupRepo.GetBy(commonRepo.WithByName(update.Name))
|
|
||||||
for _, exist := range exists {
|
|
||||||
if exist.ID != update.ID {
|
|
||||||
return buserr.New(constant.ErrNameIsExist)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return websiteGroupRepo.Save(&model.WebsiteGroup{
|
|
||||||
BaseModel: model.BaseModel{
|
|
||||||
ID: update.ID,
|
|
||||||
},
|
|
||||||
Name: update.Name,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w WebsiteGroupService) DeleteGroup(id uint) error {
|
|
||||||
websites, _ := websiteRepo.GetBy(websiteRepo.WithGroupID(id))
|
|
||||||
if len(websites) > 0 {
|
|
||||||
return buserr.New(constant.ErrGroupIsUsed)
|
|
||||||
}
|
|
||||||
return websiteGroupRepo.DeleteBy(commonRepo.WithByID(id))
|
|
||||||
}
|
|
@@ -27,6 +27,7 @@ type IWebsiteSSLService interface {
|
|||||||
GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error)
|
GetDNSResolve(req request.WebsiteDNSReq) ([]response.WebsiteDNSRes, error)
|
||||||
GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
|
GetWebsiteSSL(websiteId uint) (response.WebsiteSSLDTO, error)
|
||||||
Delete(id uint) error
|
Delete(id uint) error
|
||||||
|
Update(update request.WebsiteSSLUpdate) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIWebsiteSSLService() IWebsiteSSLService {
|
func NewIWebsiteSSLService() IWebsiteSSLService {
|
||||||
@@ -99,6 +100,10 @@ func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.Webs
|
|||||||
if err := client.UseHTTP(path.Join(constant.AppInstallDir, constant.AppOpenresty, appInstall.Name, "root")); err != nil {
|
if err := client.UseHTTP(path.Join(constant.AppInstallDir, constant.AppOpenresty, appInstall.Name, "root")); err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
case constant.DnsManual:
|
||||||
|
if err := client.UseManualDns(); err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
domains := []string{create.PrimaryDomain}
|
domains := []string{create.PrimaryDomain}
|
||||||
@@ -128,6 +133,7 @@ func (w WebsiteSSLService) Create(create request.WebsiteSSLCreate) (request.Webs
|
|||||||
websiteSSL.StartDate = cert.NotBefore
|
websiteSSL.StartDate = cert.NotBefore
|
||||||
websiteSSL.Type = cert.Issuer.CommonName
|
websiteSSL.Type = cert.Issuer.CommonName
|
||||||
websiteSSL.Organization = cert.Issuer.Organization[0]
|
websiteSSL.Organization = cert.Issuer.Organization[0]
|
||||||
|
websiteSSL.AutoRenew = create.AutoRenew
|
||||||
|
|
||||||
if err := websiteSSLRepo.Create(context.TODO(), &websiteSSL); err != nil {
|
if err := websiteSSLRepo.Create(context.TODO(), &websiteSSL); err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
@@ -254,3 +260,12 @@ func (w WebsiteSSLService) Delete(id uint) error {
|
|||||||
}
|
}
|
||||||
return websiteSSLRepo.DeleteBy(commonRepo.WithByID(id))
|
return websiteSSLRepo.DeleteBy(commonRepo.WithByID(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w WebsiteSSLService) Update(update request.WebsiteSSLUpdate) error {
|
||||||
|
websiteSSL, err := websiteSSLRepo.GetFirst(commonRepo.WithByID(update.ID))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
websiteSSL.AutoRenew = update.AutoRenew
|
||||||
|
return websiteSSLRepo.Save(websiteSSL)
|
||||||
|
}
|
||||||
|
@@ -50,15 +50,16 @@ var (
|
|||||||
|
|
||||||
// app
|
// app
|
||||||
var (
|
var (
|
||||||
ErrPortInUsed = "ErrPortInUsed"
|
ErrPortInUsed = "ErrPortInUsed"
|
||||||
ErrAppLimit = "ErrAppLimit"
|
ErrAppLimit = "ErrAppLimit"
|
||||||
ErrAppRequired = "ErrAppRequired"
|
ErrAppRequired = "ErrAppRequired"
|
||||||
ErrFileCanNotRead = "ErrFileCanNotRead"
|
ErrFileCanNotRead = "ErrFileCanNotRead"
|
||||||
ErrFileToLarge = "ErrFileToLarge"
|
ErrFileToLarge = "ErrFileToLarge"
|
||||||
ErrNotInstall = "ErrNotInstall"
|
ErrNotInstall = "ErrNotInstall"
|
||||||
ErrPortInOtherApp = "ErrPortInOtherApp"
|
ErrPortInOtherApp = "ErrPortInOtherApp"
|
||||||
ErrDbUserNotValid = "ErrDbUserNotValid"
|
ErrDbUserNotValid = "ErrDbUserNotValid"
|
||||||
ErrUpdateBuWebsite = "ErrUpdateBuWebsite"
|
ErrUpdateBuWebsite = "ErrUpdateBuWebsite"
|
||||||
|
Err1PanelNetworkFailed = "Err1PanelNetworkFailed"
|
||||||
)
|
)
|
||||||
|
|
||||||
//website
|
//website
|
||||||
@@ -83,6 +84,7 @@ var (
|
|||||||
ErrMovePathFailed = "ErrMovePathFailed"
|
ErrMovePathFailed = "ErrMovePathFailed"
|
||||||
ErrLinkPathNotFound = "ErrLinkPathNotFound"
|
ErrLinkPathNotFound = "ErrLinkPathNotFound"
|
||||||
ErrFileIsExit = "ErrFileIsExit"
|
ErrFileIsExit = "ErrFileIsExit"
|
||||||
|
ErrFileUpload = "ErrFileUpload"
|
||||||
)
|
)
|
||||||
|
|
||||||
//mysql
|
//mysql
|
||||||
@@ -95,3 +97,9 @@ var (
|
|||||||
var (
|
var (
|
||||||
ErrTypeOfRedis = "ErrTypeOfRedis"
|
ErrTypeOfRedis = "ErrTypeOfRedis"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//container
|
||||||
|
var (
|
||||||
|
ErrInUsed = "ErrInUsed"
|
||||||
|
ErrObjectInUsed = "ErrObjectInUsed"
|
||||||
|
)
|
||||||
|
@@ -4,8 +4,9 @@ const (
|
|||||||
WebRunning = "Running"
|
WebRunning = "Running"
|
||||||
WebStopped = "Stopped"
|
WebStopped = "Stopped"
|
||||||
|
|
||||||
DateLayout = "2006-01-02"
|
DateLayout = "2006-01-02"
|
||||||
DefaultDate = "1970-01-01"
|
DateTimeLayout = "2006-01-02 15:04:05"
|
||||||
|
DefaultDate = "1970-01-01"
|
||||||
|
|
||||||
ProtocolHTTP = "HTTP"
|
ProtocolHTTP = "HTTP"
|
||||||
ProtocolHTTPS = "HTTPS"
|
ProtocolHTTPS = "HTTPS"
|
||||||
|
@@ -118,6 +118,9 @@ func loadNetIO() {
|
|||||||
netStatAll2, _ := net.IOCounters(false)
|
netStatAll2, _ := net.IOCounters(false)
|
||||||
for _, net2 := range netStatAll2 {
|
for _, net2 := range netStatAll2 {
|
||||||
for _, net1 := range netStatAll {
|
for _, net1 := range netStatAll {
|
||||||
|
if net1.BytesSent == 0 || net1.BytesRecv == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if net2.Name == net1.Name {
|
if net2.Name == net1.Name {
|
||||||
var itemNet model.MonitorNetwork
|
var itemNet model.MonitorNetwork
|
||||||
itemNet.Name = net1.Name
|
itemNet.Name = net1.Name
|
||||||
|
@@ -3,6 +3,7 @@ package job
|
|||||||
import (
|
import (
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
"github.com/1Panel-dev/1Panel/backend/app/repo"
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/service"
|
"github.com/1Panel-dev/1Panel/backend/app/service"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -19,18 +20,18 @@ func (ssl *ssl) Run() {
|
|||||||
sslService := service.NewIWebsiteSSLService()
|
sslService := service.NewIWebsiteSSLService()
|
||||||
sslList, _ := sslRepo.List()
|
sslList, _ := sslRepo.List()
|
||||||
global.LOG.Info("ssl renew cron job start...")
|
global.LOG.Info("ssl renew cron job start...")
|
||||||
now := time.Now()
|
now := time.Now().Add(10 * time.Second)
|
||||||
for _, s := range sslList {
|
for _, s := range sslList {
|
||||||
if !s.AutoRenew || s.Provider == "manual" || s.Provider == "dnsManual" {
|
if !s.AutoRenew || s.Provider == "manual" || s.Provider == "dnsManual" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
sum := s.ExpireDate.Sub(now)
|
expireDate, _ := time.ParseInLocation(constant.DateTimeLayout, s.ExpireDate.String(), time.Now().Location())
|
||||||
if sum.Hours() < 168 {
|
sum := expireDate.Sub(now)
|
||||||
|
if sum.Hours() < 720 {
|
||||||
if err := sslService.Renew(s.ID); err != nil {
|
if err := sslService.Renew(s.ID); err != nil {
|
||||||
global.LOG.Errorf("renew doamin [%s] ssl failed err:%s", s.PrimaryDomain, err.Error())
|
global.LOG.Errorf("renew doamin [%s] ssl failed err:%s", s.PrimaryDomain, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global.LOG.Info("ssl renew cron job end...")
|
global.LOG.Info("ssl renew cron job end...")
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,7 @@ func NewWebsiteJob() *website {
|
|||||||
func (w *website) Run() {
|
func (w *website) Run() {
|
||||||
websites, _ := repo.NewIWebsiteRepo().List()
|
websites, _ := repo.NewIWebsiteRepo().List()
|
||||||
global.LOG.Info("website cron job start...")
|
global.LOG.Info("website cron job start...")
|
||||||
now := time.Now()
|
now := time.Now().Add(10 * time.Second)
|
||||||
if len(websites) > 0 {
|
if len(websites) > 0 {
|
||||||
neverExpireDate, _ := time.Parse(constant.DateLayout, constant.DefaultDate)
|
neverExpireDate, _ := time.Parse(constant.DateLayout, constant.DefaultDate)
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
@@ -28,7 +28,8 @@ func (w *website) Run() {
|
|||||||
if site.Status != constant.WebRunning || neverExpireDate.Equal(site.ExpireDate) {
|
if site.Status != constant.WebRunning || neverExpireDate.Equal(site.ExpireDate) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if site.ExpireDate.Before(now) {
|
expireDate, _ := time.ParseInLocation(constant.DateTimeLayout, site.ExpireDate.String(), time.Now().Location())
|
||||||
|
if expireDate.Before(now) {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(ws model.Website) {
|
go func(ws model.Website) {
|
||||||
stopWebsite(ws.ID, &wg)
|
stopWebsite(ws.ID, &wg)
|
||||||
|
@@ -11,35 +11,35 @@ import (
|
|||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetMsgWithMap(msg string, maps map[string]interface{}) string {
|
func GetMsgWithMap(key string, maps map[string]interface{}) string {
|
||||||
content := ""
|
content := ""
|
||||||
if maps == nil {
|
if maps == nil {
|
||||||
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: msg,
|
MessageID: key,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: msg,
|
MessageID: key,
|
||||||
TemplateData: maps,
|
TemplateData: maps,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
content = strings.ReplaceAll(content, ": <no value>", "")
|
content = strings.ReplaceAll(content, ": <no value>", "")
|
||||||
if content == "" {
|
if content == "" {
|
||||||
return msg
|
return key
|
||||||
} else {
|
} else {
|
||||||
return content
|
return content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetErrMsg(msg string, maps map[string]interface{}) string {
|
func GetErrMsg(key string, maps map[string]interface{}) string {
|
||||||
content := ""
|
content := ""
|
||||||
if maps == nil {
|
if maps == nil {
|
||||||
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: msg,
|
MessageID: key,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
content = ginI18n.MustGetMessage(&i18n.LocalizeConfig{
|
||||||
MessageID: msg,
|
MessageID: key,
|
||||||
TemplateData: maps,
|
TemplateData: maps,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ ErrPortInOtherApp: "{{ .port }} port already in use by {{ .apps }}"
|
|||||||
ErrDbUserNotValid: "Stock database, username and password do not match!"
|
ErrDbUserNotValid: "Stock database, username and password do not match!"
|
||||||
ErrDockerComposeNotValid: "docker-compose file format error!"
|
ErrDockerComposeNotValid: "docker-compose file format error!"
|
||||||
ErrUpdateBuWebsite: 'The application was updated successfully, but the modification of the website configuration file failed, please check the configuration!'
|
ErrUpdateBuWebsite: 'The application was updated successfully, but the modification of the website configuration file failed, please check the configuration!'
|
||||||
|
Err1PanelNetworkFailed: 'Default container network creation failed! {{ .detail }}'
|
||||||
|
|
||||||
#file
|
#file
|
||||||
ErrFileCanNotRead: "File can not read"
|
ErrFileCanNotRead: "File can not read"
|
||||||
@@ -34,6 +35,7 @@ ErrPathNotFound: "Path is not found"
|
|||||||
ErrMovePathFailed: "The target path cannot contain the original path!"
|
ErrMovePathFailed: "The target path cannot contain the original path!"
|
||||||
ErrLinkPathNotFound: "Target path does not exist!"
|
ErrLinkPathNotFound: "Target path does not exist!"
|
||||||
ErrFileIsExit: "File already exists!"
|
ErrFileIsExit: "File already exists!"
|
||||||
|
ErrFileUpload: "Failed to upload file"
|
||||||
|
|
||||||
#website
|
#website
|
||||||
ErrDomainIsExist: "Domain is already exist"
|
ErrDomainIsExist: "Domain is already exist"
|
||||||
@@ -52,4 +54,8 @@ ErrUserIsExist: "The current user already exists. Please enter a new user"
|
|||||||
ErrDatabaseIsExist: "The current database already exists. Please enter a new database"
|
ErrDatabaseIsExist: "The current database already exists. Please enter a new database"
|
||||||
|
|
||||||
#redis
|
#redis
|
||||||
ErrTypeOfRedis: "The recovery file type does not match the current persistence mode. Modify the file type and try again"
|
ErrTypeOfRedis: "The recovery file type does not match the current persistence mode. Modify the file type and try again"
|
||||||
|
|
||||||
|
#container
|
||||||
|
ErrInUsed: "{{ .detail }} is in use and cannot be deleted"
|
||||||
|
ErrObjectInUsed: "This object is in use and cannot be deleted"
|
@@ -26,6 +26,7 @@ ErrPortInOtherApp: "{{ .port }} 端口已被 {{ .apps }}占用!"
|
|||||||
ErrDbUserNotValid: "存量数据库,用户名密码不匹配!"
|
ErrDbUserNotValid: "存量数据库,用户名密码不匹配!"
|
||||||
ErrDockerComposeNotValid: "docker-compose 文件格式错误"
|
ErrDockerComposeNotValid: "docker-compose 文件格式错误"
|
||||||
ErrUpdateBuWebsite: '应用更新成功,但是网站配置文件修改失败,请检查配置!'
|
ErrUpdateBuWebsite: '应用更新成功,但是网站配置文件修改失败,请检查配置!'
|
||||||
|
Err1PanelNetworkFailed: '默认容器网络创建失败!{{ .detail }}'
|
||||||
|
|
||||||
#file
|
#file
|
||||||
ErrFileCanNotRead: "此文件不支持预览"
|
ErrFileCanNotRead: "此文件不支持预览"
|
||||||
@@ -34,6 +35,7 @@ ErrPathNotFound: "目录不存在"
|
|||||||
ErrMovePathFailed: "目标路径不能包含原路径!"
|
ErrMovePathFailed: "目标路径不能包含原路径!"
|
||||||
ErrLinkPathNotFound: "目标路径不存在!"
|
ErrLinkPathNotFound: "目标路径不存在!"
|
||||||
ErrFileIsExit: "文件已存在!"
|
ErrFileIsExit: "文件已存在!"
|
||||||
|
ErrFileUpload: "上传文件失败"
|
||||||
|
|
||||||
#website
|
#website
|
||||||
ErrDomainIsExist: "域名已存在"
|
ErrDomainIsExist: "域名已存在"
|
||||||
@@ -52,4 +54,8 @@ ErrUserIsExist: "当前用户已存在,请重新输入"
|
|||||||
ErrDatabaseIsExist: "当前数据库已存在,请重新输入"
|
ErrDatabaseIsExist: "当前数据库已存在,请重新输入"
|
||||||
|
|
||||||
#redis
|
#redis
|
||||||
ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后重试"
|
ErrTypeOfRedis: "恢复文件类型与当前持久化方式不符,请修改后重试"
|
||||||
|
|
||||||
|
#container
|
||||||
|
ErrInUsed: "{{ .detail }} 正被使用,无法删除"
|
||||||
|
ErrObjectInUsed: "该对象正被使用,无法删除"
|
@@ -1,12 +1,11 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/constant"
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/docker"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ func Init() {
|
|||||||
createDir(fileOp, dir)
|
createDir(fileOp, dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
createDefaultDockerNetwork()
|
_ = docker.CreateDefaultDockerNetwork()
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDir(fileOp files.FileOp, dirPath string) {
|
func createDir(fileOp files.FileOp, dirPath string) {
|
||||||
@@ -31,17 +30,3 @@ func createDir(fileOp files.FileOp, dirPath string) {
|
|||||||
_ = fileOp.CreateDir(dirPath, 0755)
|
_ = fileOp.CreateDir(dirPath, 0755)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createDefaultDockerNetwork() {
|
|
||||||
cli, err := docker.NewClient()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("init docker client error", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !cli.NetworkExist("1panel-network") {
|
|
||||||
if err := cli.CreateNetwork("1panel-network"); err != nil {
|
|
||||||
fmt.Println("init docker client error", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -1,25 +1,35 @@
|
|||||||
package business
|
package business
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/app/service"
|
"github.com/1Panel-dev/1Panel/backend/app/service"
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
|
syncApp()
|
||||||
|
syncInstalledApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
func syncApp() {
|
||||||
setting, err := service.NewISettingService().GetSettingInfo()
|
setting, err := service.NewISettingService().GetSettingInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.LOG.Errorf("sync app error: %s", err.Error())
|
global.LOG.Errorf("sync app error: %s", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if setting.AppStoreVersion != "" {
|
if setting.AppStoreVersion != "" {
|
||||||
fmt.Println(setting.AppStoreVersion)
|
global.LOG.Info("no need to sync")
|
||||||
global.LOG.Info("do not sync")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
global.LOG.Info("sync app start...")
|
global.LOG.Info("sync app start...")
|
||||||
if err := service.NewIAppService().SyncAppList(); err != nil {
|
if err := service.NewIAppService().SyncAppList(); err != nil {
|
||||||
global.LOG.Errorf("sync app error: %s", err.Error())
|
global.LOG.Errorf("sync app error: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
global.LOG.Info("sync app successful")
|
||||||
|
}
|
||||||
|
|
||||||
|
func syncInstalledApp() {
|
||||||
|
if err := service.NewIAppInstalledService().SyncAll(true); err != nil {
|
||||||
|
global.LOG.Errorf("sync instaled app error: %s", err.Error())
|
||||||
}
|
}
|
||||||
global.LOG.Info("sync app success")
|
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,11 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gorm.io/driver/sqlite"
|
"gorm.io/driver/sqlite"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
)
|
)
|
||||||
@@ -28,6 +30,15 @@ func Init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
_ = db.Exec("PRAGMA journal_mode = WAL;")
|
||||||
|
sqlDB, dbError := db.DB()
|
||||||
|
if dbError != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
sqlDB.SetConnMaxIdleTime(10)
|
||||||
|
sqlDB.SetMaxOpenConns(100)
|
||||||
|
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||||
|
|
||||||
global.DB = db
|
global.DB = db
|
||||||
global.LOG.Info("init db successfully")
|
global.LOG.Info("init db successfully")
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ func Init() {
|
|||||||
migrations.AddTableWebsite,
|
migrations.AddTableWebsite,
|
||||||
migrations.AddTableDatabaseMysql,
|
migrations.AddTableDatabaseMysql,
|
||||||
migrations.AddTableSnap,
|
migrations.AddTableSnap,
|
||||||
|
migrations.AddDefaultGroup,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@@ -140,7 +140,6 @@ var AddTableSetting = &gormigrate.Migration{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tx.Create(&model.Setting{Key: "SystemStatus", Value: "Free"}).Error; err != nil {
|
if err := tx.Create(&model.Setting{Key: "SystemStatus", Value: "Free"}).Error; err != nil {
|
||||||
tx.Rollback()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := tx.Create(&model.Setting{Key: "AppStoreVersion", Value: ""}).Error; err != nil {
|
if err := tx.Create(&model.Setting{Key: "AppStoreVersion", Value: ""}).Error; err != nil {
|
||||||
@@ -211,14 +210,7 @@ var AddTableDatabaseMysql = &gormigrate.Migration{
|
|||||||
var AddTableWebsite = &gormigrate.Migration{
|
var AddTableWebsite = &gormigrate.Migration{
|
||||||
ID: "20201009-add-table-website",
|
ID: "20201009-add-table-website",
|
||||||
Migrate: func(tx *gorm.DB) error {
|
Migrate: func(tx *gorm.DB) error {
|
||||||
if err := tx.AutoMigrate(&model.Website{}, &model.WebsiteDomain{}, &model.WebsiteGroup{}, &model.WebsiteDnsAccount{}, &model.WebsiteSSL{}, &model.WebsiteAcmeAccount{}); err != nil {
|
if err := tx.AutoMigrate(&model.Website{}, &model.WebsiteDomain{}, &model.WebsiteDnsAccount{}, &model.WebsiteSSL{}, &model.WebsiteAcmeAccount{}); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
item := &model.WebsiteGroup{
|
|
||||||
Name: "默认",
|
|
||||||
Default: true,
|
|
||||||
}
|
|
||||||
if err := tx.Create(item).Error; err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -234,3 +226,24 @@ var AddTableSnap = &gormigrate.Migration{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AddDefaultGroup = &gormigrate.Migration{
|
||||||
|
ID: "2023022-change-default-group",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
defaultGroup := &model.Group{
|
||||||
|
Name: "默认",
|
||||||
|
IsDefault: true,
|
||||||
|
Type: "website",
|
||||||
|
}
|
||||||
|
if err := tx.Create(defaultGroup).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Model(&model.Group{}).Where("name = ? AND type = ?", "default", "host").Update("name", "默认").Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := tx.Model(&model.Website{}).Where("1 = 1").Update("website_group_id", defaultGroup.ID).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return tx.Migrator().DropTable("website_groups")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
package log
|
package log
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/global"
|
|
||||||
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
@@ -14,6 +11,9 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
@@ -261,7 +261,6 @@ func (w *Writer) CompressFile(logFile string) error {
|
|||||||
comFileName := path.Base(logFile) + ".gz"
|
comFileName := path.Base(logFile) + ".gz"
|
||||||
filePath := path.Dir(logFile)
|
filePath := path.Dir(logFile)
|
||||||
|
|
||||||
fmt.Println(path.Dir(logFile))
|
|
||||||
if err := op.Compress([]string{logFile}, filePath, comFileName, files.Gz); err != nil {
|
if err := op.Compress([]string{logFile}, filePath, comFileName, files.Gz); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -96,7 +96,6 @@ func OperationLog() gin.HandlerFunc {
|
|||||||
var names []string
|
var names []string
|
||||||
if funcs.IsList {
|
if funcs.IsList {
|
||||||
sql := fmt.Sprintf("SELECT %s FROM %s where %s in (?);", funcs.OutputColume, funcs.DB, funcs.InputColume)
|
sql := fmt.Sprintf("SELECT %s FROM %s where %s in (?);", funcs.OutputColume, funcs.DB, funcs.InputColume)
|
||||||
fmt.Println(value)
|
|
||||||
_ = global.DB.Raw(sql, value).Scan(&names)
|
_ = global.DB.Raw(sql, value).Scan(&names)
|
||||||
} else {
|
} else {
|
||||||
_ = global.DB.Raw(fmt.Sprintf("select %s from %s where %s = ?;", funcs.OutputColume, funcs.DB, funcs.InputColume), value).Scan(&names)
|
_ = global.DB.Raw(fmt.Sprintf("select %s from %s where %s = ?;", funcs.OutputColume, funcs.DB, funcs.InputColume), value).Scan(&names)
|
||||||
|
@@ -33,6 +33,7 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) {
|
|||||||
|
|
||||||
baRouter.POST("/compose/search", baseApi.SearchCompose)
|
baRouter.POST("/compose/search", baseApi.SearchCompose)
|
||||||
baRouter.POST("/compose", baseApi.CreateCompose)
|
baRouter.POST("/compose", baseApi.CreateCompose)
|
||||||
|
baRouter.POST("/compose/test", baseApi.TestCompose)
|
||||||
baRouter.POST("/compose/operate", baseApi.OperatorCompose)
|
baRouter.POST("/compose/operate", baseApi.OperatorCompose)
|
||||||
baRouter.POST("/compose/update", baseApi.ComposeUpdate)
|
baRouter.POST("/compose/update", baseApi.ComposeUpdate)
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) {
|
|||||||
fileRouter.POST("/wget", baseApi.WgetFile)
|
fileRouter.POST("/wget", baseApi.WgetFile)
|
||||||
fileRouter.POST("/move", baseApi.MoveFile)
|
fileRouter.POST("/move", baseApi.MoveFile)
|
||||||
fileRouter.POST("/download", baseApi.Download)
|
fileRouter.POST("/download", baseApi.Download)
|
||||||
|
fileRouter.POST("/download/bypath", baseApi.DownloadFile)
|
||||||
fileRouter.POST("/size", baseApi.Size)
|
fileRouter.POST("/size", baseApi.Size)
|
||||||
fileRouter.GET("/ws", baseApi.Ws)
|
fileRouter.GET("/ws", baseApi.Ws)
|
||||||
fileRouter.GET("/keys", baseApi.Keys)
|
fileRouter.GET("/keys", baseApi.Keys)
|
||||||
|
@@ -10,14 +10,14 @@ type WebsiteGroupRouter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *WebsiteGroupRouter) InitWebsiteGroupRouter(Router *gin.RouterGroup) {
|
func (a *WebsiteGroupRouter) InitWebsiteGroupRouter(Router *gin.RouterGroup) {
|
||||||
groupRouter := Router.Group("websites/groups")
|
groupRouter := Router.Group("groups")
|
||||||
groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired())
|
groupRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).Use(middleware.PasswordExpired())
|
||||||
|
|
||||||
baseApi := v1.ApiGroupApp.BaseApi
|
baseApi := v1.ApiGroupApp.BaseApi
|
||||||
{
|
{
|
||||||
groupRouter.GET("", baseApi.GetWebGroups)
|
groupRouter.POST("", baseApi.CreateGroup)
|
||||||
groupRouter.POST("", baseApi.CreateWebGroup)
|
groupRouter.POST("/del", baseApi.DeleteGroup)
|
||||||
groupRouter.POST("/update", baseApi.UpdateWebGroup)
|
groupRouter.POST("/update", baseApi.UpdateGroup)
|
||||||
groupRouter.POST("/del", baseApi.DeleteWebGroup)
|
groupRouter.POST("/search", baseApi.ListGroup)
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -26,11 +26,6 @@ func (s *HostRouter) InitHostRouter(Router *gin.RouterGroup) {
|
|||||||
hostRouter.POST("/test/byid/:id", baseApi.TestByID)
|
hostRouter.POST("/test/byid/:id", baseApi.TestByID)
|
||||||
hostRouter.GET(":id", baseApi.GetHostInfo)
|
hostRouter.GET(":id", baseApi.GetHostInfo)
|
||||||
|
|
||||||
hostRouter.POST("/group", baseApi.CreateGroup)
|
|
||||||
hostRouter.POST("/group/del", baseApi.DeleteGroup)
|
|
||||||
hostRouter.POST("/group/update", baseApi.UpdateGroup)
|
|
||||||
hostRouter.POST("/group/search", baseApi.ListGroup)
|
|
||||||
|
|
||||||
hostRouter.GET("/command", baseApi.ListCommand)
|
hostRouter.GET("/command", baseApi.ListCommand)
|
||||||
hostRouter.POST("/command", baseApi.CreateCommand)
|
hostRouter.POST("/command", baseApi.CreateCommand)
|
||||||
hostRouter.POST("/command/del", baseApi.DeleteCommand)
|
hostRouter.POST("/command/del", baseApi.DeleteCommand)
|
||||||
|
@@ -51,6 +51,7 @@ func (s *SettingRouter) InitSettingRouter(Router *gin.RouterGroup) {
|
|||||||
settingRouter.POST("/backup/record/del", baseApi.DeleteBackupRecord)
|
settingRouter.POST("/backup/record/del", baseApi.DeleteBackupRecord)
|
||||||
|
|
||||||
settingRouter.POST("/upgrade", baseApi.Upgrade)
|
settingRouter.POST("/upgrade", baseApi.Upgrade)
|
||||||
|
settingRouter.POST("/upgrade/notes", baseApi.GetNotesByVersion)
|
||||||
settingRouter.GET("/upgrade", baseApi.GetUpgradeInfo)
|
settingRouter.GET("/upgrade", baseApi.GetUpgradeInfo)
|
||||||
settingRouter.GET("/basedir", baseApi.LoadBaseDir)
|
settingRouter.GET("/basedir", baseApi.LoadBaseDir)
|
||||||
}
|
}
|
||||||
|
@@ -22,5 +22,6 @@ func (a *WebsiteSSLRouter) InitWebsiteSSLRouter(Router *gin.RouterGroup) {
|
|||||||
groupRouter.POST("/del", baseApi.DeleteWebsiteSSL)
|
groupRouter.POST("/del", baseApi.DeleteWebsiteSSL)
|
||||||
groupRouter.GET("/website/:websiteId", baseApi.GetWebsiteSSLByWebsiteId)
|
groupRouter.GET("/website/:websiteId", baseApi.GetWebsiteSSLByWebsiteId)
|
||||||
groupRouter.GET("/:id", baseApi.GetWebsiteSSLById)
|
groupRouter.GET("/:id", baseApi.GetWebsiteSSLById)
|
||||||
|
groupRouter.POST("/update", baseApi.UpdateWebsiteSSL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -77,7 +77,7 @@ func (oss ossClient) Upload(src, target string) (bool, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
err = bucket.PutObjectFromFile(target, src)
|
err = bucket.UploadFile(target, src, 200*1024*1024, osssdk.Routines(5), osssdk.Checkpoint(true, ""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@ func (oss ossClient) Download(src, target string) (bool, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
err = bucket.GetObjectToFile(src, target)
|
err = bucket.DownloadFile(src, target, 200*1024*1024, osssdk.Routines(5), osssdk.Checkpoint(true, ""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package docker
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/1Panel-dev/1Panel/backend/global"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
@@ -73,3 +74,18 @@ func (c Client) NetworkExist(name string) bool {
|
|||||||
}
|
}
|
||||||
return len(networks) > 0
|
return len(networks) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateDefaultDockerNetwork() error {
|
||||||
|
cli, err := NewClient()
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("init docker client error %s", err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !cli.NetworkExist("1panel-network") {
|
||||||
|
if err := cli.CreateNetwork("1panel-network"); err != nil {
|
||||||
|
global.LOG.Errorf("create default docker network error %s", err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -1,21 +0,0 @@
|
|||||||
package ssh
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSSH(t *testing.T) {
|
|
||||||
ss := ConnInfo{
|
|
||||||
Addr: "172.16.10.111",
|
|
||||||
Port: 22,
|
|
||||||
User: "root",
|
|
||||||
AuthMode: "password",
|
|
||||||
Password: "Calong@2015",
|
|
||||||
}
|
|
||||||
_, err := ss.NewClient()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
fmt.Println(ss.Run("ip a"))
|
|
||||||
}
|
|
@@ -89,6 +89,7 @@ func NewPrivateKeyClient(email string, privateKey string) (*AcmeClient, error) {
|
|||||||
func newConfig(user *AcmeUser) *lego.Config {
|
func newConfig(user *AcmeUser) *lego.Config {
|
||||||
config := lego.NewConfig(user)
|
config := lego.NewConfig(user)
|
||||||
config.CADirURL = "https://acme-v02.api.letsencrypt.org/directory"
|
config.CADirURL = "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
|
//config.CADirURL = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
config.UserAgent = "acm_go/0.0.1"
|
config.UserAgent = "acm_go/0.0.1"
|
||||||
config.Certificate.KeyType = certcrypto.RSA2048
|
config.Certificate.KeyType = certcrypto.RSA2048
|
||||||
return config
|
return config
|
||||||
|
@@ -9,6 +9,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/go-acme/lego/v4/acme/api"
|
"github.com/go-acme/lego/v4/acme/api"
|
||||||
"github.com/go-acme/lego/v4/certcrypto"
|
"github.com/go-acme/lego/v4/certcrypto"
|
||||||
@@ -154,10 +155,10 @@ func TestSSL(t *testing.T) {
|
|||||||
// panic(err)
|
// panic(err)
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// err = client.Challenge.SetDNS01Provider(&plainDnsProvider{}, dns01.AddDNSTimeout(6*time.Minute))
|
err = client.Challenge.SetDNS01Provider(&manualDnsProvider{}, dns01.AddDNSTimeout(6*time.Minute))
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// panic(err)
|
panic(err)
|
||||||
// }
|
}
|
||||||
|
|
||||||
core, err := api.New(config.HTTPClient, config.UserAgent, config.CADirURL, reg.URI, priKey)
|
core, err := api.New(config.HTTPClient, config.UserAgent, config.CADirURL, reg.URI, priKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -115,22 +115,12 @@ func (c *AcmeClient) UseDns(dnsType DnsType, params string) error {
|
|||||||
return c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(3*time.Minute))
|
return c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(3*time.Minute))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AcmeClient) UseManualDns(domains []string) (*Resolve, error) {
|
func (c *AcmeClient) UseManualDns() error {
|
||||||
p := &manualDnsProvider{}
|
p := &manualDnsProvider{}
|
||||||
if err := c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(3*time.Minute)); err != nil {
|
if err := c.Client.Challenge.SetDNS01Provider(p, dns01.AddDNSTimeout(3*time.Minute)); err != nil {
|
||||||
return nil, nil
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
request := certificate.ObtainRequest{
|
|
||||||
Domains: domains,
|
|
||||||
Bundle: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := c.Client.Certificate.Obtain(request)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return p.Resolve, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *AcmeClient) UseHTTP(path string) error {
|
func (c *AcmeClient) UseHTTP(path string) error {
|
||||||
|
@@ -62,6 +62,25 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/apps/checkupdate": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "获取应用更新版本",
|
||||||
|
"tags": [
|
||||||
|
"App"
|
||||||
|
],
|
||||||
|
"summary": "Get app list update",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/apps/detail/:appId/:version": {
|
"/apps/detail/:appId/:version": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -470,6 +489,48 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/apps/installed/params/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "修改应用参数",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"App"
|
||||||
|
],
|
||||||
|
"summary": "Change app params",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.AppInstalledUpdate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"installId"
|
||||||
|
],
|
||||||
|
"formatEN": "Application param update [installId]",
|
||||||
|
"formatZH": "应用参数修改 [installId]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/apps/installed/port/change": {
|
"/apps/installed/port/change": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -683,6 +744,20 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/auth/demo": {
|
||||||
|
"get": {
|
||||||
|
"description": "判断是否为demo环境",
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Check System isDemo",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/auth/init": {
|
"/auth/init": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "初始化用户",
|
"description": "初始化用户",
|
||||||
@@ -970,6 +1045,48 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/containers/compose/test": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "测试 compose 是否可用",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Container Compose"
|
||||||
|
],
|
||||||
|
"summary": "Test compose",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.ComposeCreate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"formatEN": "check compose [name]",
|
||||||
|
"formatZH": "检测 compose [name] 格式",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/containers/compose/update": {
|
"/containers/compose/update": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3899,6 +4016,34 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/chunkupload": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "分片上传文件",
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "ChunkUpload file",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"description": "request",
|
||||||
|
"name": "file",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/compress": {
|
"/files/compress": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -4112,6 +4257,48 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/download/bypath": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "下载指定文件",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "Download file with path",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.FilePath"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"formatEN": "Download file [path]",
|
||||||
|
"formatZH": "下载文件 [path]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/loadfile": {
|
"/files/loadfile": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -6706,17 +6893,28 @@ var doc = `{
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "系统更新信息",
|
"description": "获取版本 release notes",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"System Setting"
|
"System Setting"
|
||||||
],
|
],
|
||||||
"summary": "Load upgrade info",
|
"summary": "Load release notes by version",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.Upgrade"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK"
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.UpgradeInfo"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -8256,6 +8454,57 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/websites/ssl/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "更新 ssl",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Website SSL"
|
||||||
|
],
|
||||||
|
"summary": "Update ssl",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.WebsiteSSLUpdate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [
|
||||||
|
{
|
||||||
|
"db": "website_ssls",
|
||||||
|
"input_colume": "id",
|
||||||
|
"input_value": "id",
|
||||||
|
"isList": false,
|
||||||
|
"output_colume": "primary_domain",
|
||||||
|
"output_value": "domain"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bodyKeys": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"formatEN": "Update ssl config [domain]",
|
||||||
|
"formatZH": "更新证书设置 [domain]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/websites/ssl/website/:websiteId": {
|
"/websites/ssl/website/:websiteId": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -8623,8 +8872,7 @@ var doc = `{
|
|||||||
"dto.ComposeCreate": {
|
"dto.ComposeCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"from",
|
"from"
|
||||||
"name"
|
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"file": {
|
"file": {
|
||||||
@@ -8860,9 +9108,7 @@ var doc = `{
|
|||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"day": {
|
"day": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 31,
|
|
||||||
"minimum": 1
|
|
||||||
},
|
},
|
||||||
"dbName": {
|
"dbName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -8871,17 +9117,13 @@ var doc = `{
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"hour": {
|
"hour": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 23,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"keepLocal": {
|
"keepLocal": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"minute": {
|
"minute": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 59,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -8942,9 +9184,7 @@ var doc = `{
|
|||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"day": {
|
"day": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 31,
|
|
||||||
"minimum": 1
|
|
||||||
},
|
},
|
||||||
"dbName": {
|
"dbName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -8953,9 +9193,7 @@ var doc = `{
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"hour": {
|
"hour": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 23,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
@@ -8964,9 +9202,7 @@ var doc = `{
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"minute": {
|
"minute": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 59,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -9060,15 +9296,9 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"dto.DaemonJsonUpdateByFile": {
|
"dto.DaemonJsonUpdateByFile": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"path"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"file": {
|
"file": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
|
||||||
"path": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -9254,6 +9484,12 @@ var doc = `{
|
|||||||
"restart",
|
"restart",
|
||||||
"stop"
|
"stop"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"stopService": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"stopSocket": {
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -10511,6 +10747,9 @@ var doc = `{
|
|||||||
"dto.UpgradeInfo": {
|
"dto.UpgradeInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"latestVersion": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"newVersion": {
|
"newVersion": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -11042,6 +11281,22 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.AppInstalledUpdate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"installId",
|
||||||
|
"params"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"installId": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.AppSearch": {
|
"request.AppSearch": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -11819,6 +12074,21 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.WebsiteSSLUpdate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"autoRenew",
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"autoRenew": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.WebsiteSearch": {
|
"request.WebsiteSearch": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -12042,10 +12312,29 @@ var doc = `{
|
|||||||
"response.AppParam": {
|
"response.AppParam": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"label": {
|
"edit": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"value": {}
|
"labelEn": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"labelZh": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"rule": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"showValue": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {},
|
||||||
|
"values": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response.FileInfo": {
|
"response.FileInfo": {
|
||||||
@@ -12185,6 +12474,9 @@ var doc = `{
|
|||||||
"appInstallId": {
|
"appInstallId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"appName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@@ -48,6 +48,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/apps/checkupdate": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "获取应用更新版本",
|
||||||
|
"tags": [
|
||||||
|
"App"
|
||||||
|
],
|
||||||
|
"summary": "Get app list update",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/apps/detail/:appId/:version": {
|
"/apps/detail/:appId/:version": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -456,6 +475,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/apps/installed/params/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "修改应用参数",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"App"
|
||||||
|
],
|
||||||
|
"summary": "Change app params",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.AppInstalledUpdate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"installId"
|
||||||
|
],
|
||||||
|
"formatEN": "Application param update [installId]",
|
||||||
|
"formatZH": "应用参数修改 [installId]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/apps/installed/port/change": {
|
"/apps/installed/port/change": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -669,6 +730,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/auth/demo": {
|
||||||
|
"get": {
|
||||||
|
"description": "判断是否为demo环境",
|
||||||
|
"tags": [
|
||||||
|
"Auth"
|
||||||
|
],
|
||||||
|
"summary": "Check System isDemo",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/auth/init": {
|
"/auth/init": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "初始化用户",
|
"description": "初始化用户",
|
||||||
@@ -956,6 +1031,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/containers/compose/test": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "测试 compose 是否可用",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Container Compose"
|
||||||
|
],
|
||||||
|
"summary": "Test compose",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.ComposeCreate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"formatEN": "check compose [name]",
|
||||||
|
"formatZH": "检测 compose [name] 格式",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/containers/compose/update": {
|
"/containers/compose/update": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3885,6 +4002,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/chunkupload": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "分片上传文件",
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "ChunkUpload file",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "file",
|
||||||
|
"description": "request",
|
||||||
|
"name": "file",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/compress": {
|
"/files/compress": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -4098,6 +4243,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/download/bypath": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "下载指定文件",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "Download file with path",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.FilePath"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"formatEN": "Download file [path]",
|
||||||
|
"formatZH": "下载文件 [path]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/loadfile": {
|
"/files/loadfile": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -6692,17 +6879,28 @@
|
|||||||
"ApiKeyAuth": []
|
"ApiKeyAuth": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "系统更新信息",
|
"description": "获取版本 release notes",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
"tags": [
|
"tags": [
|
||||||
"System Setting"
|
"System Setting"
|
||||||
],
|
],
|
||||||
"summary": "Load upgrade info",
|
"summary": "Load release notes by version",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/dto.Upgrade"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "OK",
|
"description": "OK"
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/dto.UpgradeInfo"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -8242,6 +8440,57 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/websites/ssl/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "更新 ssl",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Website SSL"
|
||||||
|
],
|
||||||
|
"summary": "Update ssl",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.WebsiteSSLUpdate"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [
|
||||||
|
{
|
||||||
|
"db": "website_ssls",
|
||||||
|
"input_colume": "id",
|
||||||
|
"input_value": "id",
|
||||||
|
"isList": false,
|
||||||
|
"output_colume": "primary_domain",
|
||||||
|
"output_value": "domain"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bodyKeys": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"formatEN": "Update ssl config [domain]",
|
||||||
|
"formatZH": "更新证书设置 [domain]",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/websites/ssl/website/:websiteId": {
|
"/websites/ssl/website/:websiteId": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -8609,8 +8858,7 @@
|
|||||||
"dto.ComposeCreate": {
|
"dto.ComposeCreate": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"from",
|
"from"
|
||||||
"name"
|
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"file": {
|
"file": {
|
||||||
@@ -8846,9 +9094,7 @@
|
|||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"day": {
|
"day": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 31,
|
|
||||||
"minimum": 1
|
|
||||||
},
|
},
|
||||||
"dbName": {
|
"dbName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -8857,17 +9103,13 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"hour": {
|
"hour": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 23,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"keepLocal": {
|
"keepLocal": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"minute": {
|
"minute": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 59,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -8928,9 +9170,7 @@
|
|||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"day": {
|
"day": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 31,
|
|
||||||
"minimum": 1
|
|
||||||
},
|
},
|
||||||
"dbName": {
|
"dbName": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -8939,9 +9179,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"hour": {
|
"hour": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 23,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
@@ -8950,9 +9188,7 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"minute": {
|
"minute": {
|
||||||
"type": "integer",
|
"type": "integer"
|
||||||
"maximum": 59,
|
|
||||||
"minimum": 0
|
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -9046,15 +9282,9 @@
|
|||||||
},
|
},
|
||||||
"dto.DaemonJsonUpdateByFile": {
|
"dto.DaemonJsonUpdateByFile": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"path"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"file": {
|
"file": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
|
||||||
"path": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -9240,6 +9470,12 @@
|
|||||||
"restart",
|
"restart",
|
||||||
"stop"
|
"stop"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"stopService": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"stopSocket": {
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -10497,6 +10733,9 @@
|
|||||||
"dto.UpgradeInfo": {
|
"dto.UpgradeInfo": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"latestVersion": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"newVersion": {
|
"newVersion": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -11028,6 +11267,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.AppInstalledUpdate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"installId",
|
||||||
|
"params"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"installId": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.AppSearch": {
|
"request.AppSearch": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -11805,6 +12060,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.WebsiteSSLUpdate": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"autoRenew",
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"autoRenew": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.WebsiteSearch": {
|
"request.WebsiteSearch": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -12028,10 +12298,29 @@
|
|||||||
"response.AppParam": {
|
"response.AppParam": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"label": {
|
"edit": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"value": {}
|
"labelEn": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"labelZh": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"rule": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"showValue": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"value": {},
|
||||||
|
"values": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"response.FileInfo": {
|
"response.FileInfo": {
|
||||||
@@ -12171,6 +12460,9 @@
|
|||||||
"appInstallId": {
|
"appInstallId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
|
"appName": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"createdAt": {
|
"createdAt": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
@@ -152,7 +152,6 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
required:
|
required:
|
||||||
- from
|
- from
|
||||||
- name
|
|
||||||
type: object
|
type: object
|
||||||
dto.ComposeOperation:
|
dto.ComposeOperation:
|
||||||
properties:
|
properties:
|
||||||
@@ -294,22 +293,16 @@ definitions:
|
|||||||
dto.CronjobCreate:
|
dto.CronjobCreate:
|
||||||
properties:
|
properties:
|
||||||
day:
|
day:
|
||||||
maximum: 31
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
type: integer
|
||||||
dbName:
|
dbName:
|
||||||
type: string
|
type: string
|
||||||
exclusionRules:
|
exclusionRules:
|
||||||
type: string
|
type: string
|
||||||
hour:
|
hour:
|
||||||
maximum: 23
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
type: integer
|
||||||
keepLocal:
|
keepLocal:
|
||||||
type: boolean
|
type: boolean
|
||||||
minute:
|
minute:
|
||||||
maximum: 59
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
type: integer
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
@@ -352,24 +345,18 @@ definitions:
|
|||||||
dto.CronjobUpdate:
|
dto.CronjobUpdate:
|
||||||
properties:
|
properties:
|
||||||
day:
|
day:
|
||||||
maximum: 31
|
|
||||||
minimum: 1
|
|
||||||
type: integer
|
type: integer
|
||||||
dbName:
|
dbName:
|
||||||
type: string
|
type: string
|
||||||
exclusionRules:
|
exclusionRules:
|
||||||
type: string
|
type: string
|
||||||
hour:
|
hour:
|
||||||
maximum: 23
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
type: integer
|
||||||
id:
|
id:
|
||||||
type: integer
|
type: integer
|
||||||
keepLocal:
|
keepLocal:
|
||||||
type: boolean
|
type: boolean
|
||||||
minute:
|
minute:
|
||||||
maximum: 59
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
type: integer
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
@@ -439,10 +426,6 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
file:
|
file:
|
||||||
type: string
|
type: string
|
||||||
path:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- path
|
|
||||||
type: object
|
type: object
|
||||||
dto.DashboardBase:
|
dto.DashboardBase:
|
||||||
properties:
|
properties:
|
||||||
@@ -564,6 +547,10 @@ definitions:
|
|||||||
- restart
|
- restart
|
||||||
- stop
|
- stop
|
||||||
type: string
|
type: string
|
||||||
|
stopService:
|
||||||
|
type: boolean
|
||||||
|
stopSocket:
|
||||||
|
type: boolean
|
||||||
required:
|
required:
|
||||||
- operation
|
- operation
|
||||||
type: object
|
type: object
|
||||||
@@ -1402,6 +1389,8 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
dto.UpgradeInfo:
|
dto.UpgradeInfo:
|
||||||
properties:
|
properties:
|
||||||
|
latestVersion:
|
||||||
|
type: string
|
||||||
newVersion:
|
newVersion:
|
||||||
type: string
|
type: string
|
||||||
releaseNote:
|
releaseNote:
|
||||||
@@ -1752,6 +1741,17 @@ definitions:
|
|||||||
- page
|
- page
|
||||||
- pageSize
|
- pageSize
|
||||||
type: object
|
type: object
|
||||||
|
request.AppInstalledUpdate:
|
||||||
|
properties:
|
||||||
|
installId:
|
||||||
|
type: integer
|
||||||
|
params:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- installId
|
||||||
|
- params
|
||||||
|
type: object
|
||||||
request.AppSearch:
|
request.AppSearch:
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
@@ -2272,6 +2272,16 @@ definitions:
|
|||||||
- page
|
- page
|
||||||
- pageSize
|
- pageSize
|
||||||
type: object
|
type: object
|
||||||
|
request.WebsiteSSLUpdate:
|
||||||
|
properties:
|
||||||
|
autoRenew:
|
||||||
|
type: boolean
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- autoRenew
|
||||||
|
- id
|
||||||
|
type: object
|
||||||
request.WebsiteSearch:
|
request.WebsiteSearch:
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
@@ -2421,9 +2431,22 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
response.AppParam:
|
response.AppParam:
|
||||||
properties:
|
properties:
|
||||||
label:
|
edit:
|
||||||
|
type: boolean
|
||||||
|
key:
|
||||||
|
type: string
|
||||||
|
labelEn:
|
||||||
|
type: string
|
||||||
|
labelZh:
|
||||||
|
type: string
|
||||||
|
rule:
|
||||||
|
type: string
|
||||||
|
showValue:
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
type: string
|
type: string
|
||||||
value: {}
|
value: {}
|
||||||
|
values: {}
|
||||||
type: object
|
type: object
|
||||||
response.FileInfo:
|
response.FileInfo:
|
||||||
properties:
|
properties:
|
||||||
@@ -2515,6 +2538,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
appInstallId:
|
appInstallId:
|
||||||
type: integer
|
type: integer
|
||||||
|
appName:
|
||||||
|
type: string
|
||||||
createdAt:
|
createdAt:
|
||||||
type: string
|
type: string
|
||||||
defaultServer:
|
defaultServer:
|
||||||
@@ -2628,6 +2653,17 @@ paths:
|
|||||||
summary: Search app by key
|
summary: Search app by key
|
||||||
tags:
|
tags:
|
||||||
- App
|
- App
|
||||||
|
/apps/checkupdate:
|
||||||
|
get:
|
||||||
|
description: 获取应用更新版本
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Get app list update
|
||||||
|
tags:
|
||||||
|
- App
|
||||||
/apps/detail/:appId/:version:
|
/apps/detail/:appId/:version:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -2887,6 +2923,33 @@ paths:
|
|||||||
summary: Search params by appInstallId
|
summary: Search params by appInstallId
|
||||||
tags:
|
tags:
|
||||||
- App
|
- App
|
||||||
|
/apps/installed/params/update:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 修改应用参数
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.AppInstalledUpdate'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Change app params
|
||||||
|
tags:
|
||||||
|
- App
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- installId
|
||||||
|
formatEN: Application param update [installId]
|
||||||
|
formatZH: 应用参数修改 [installId]
|
||||||
|
paramKeys: []
|
||||||
/apps/installed/port/change:
|
/apps/installed/port/change:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -3022,6 +3085,15 @@ paths:
|
|||||||
summary: Load captcha
|
summary: Load captcha
|
||||||
tags:
|
tags:
|
||||||
- Auth
|
- Auth
|
||||||
|
/auth/demo:
|
||||||
|
get:
|
||||||
|
description: 判断是否为demo环境
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
summary: Check System isDemo
|
||||||
|
tags:
|
||||||
|
- Auth
|
||||||
/auth/init:
|
/auth/init:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -3205,6 +3277,33 @@ paths:
|
|||||||
summary: Page composes
|
summary: Page composes
|
||||||
tags:
|
tags:
|
||||||
- Container Compose
|
- Container Compose
|
||||||
|
/containers/compose/test:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 测试 compose 是否可用
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.ComposeCreate'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Test compose
|
||||||
|
tags:
|
||||||
|
- Container Compose
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- name
|
||||||
|
formatEN: check compose [name]
|
||||||
|
formatZH: 检测 compose [name] 格式
|
||||||
|
paramKeys: []
|
||||||
/containers/compose/update:
|
/containers/compose/update:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -5065,6 +5164,23 @@ paths:
|
|||||||
formatEN: Check whether file [path] exists
|
formatEN: Check whether file [path] exists
|
||||||
formatZH: 检测文件 [path] 是否存在
|
formatZH: 检测文件 [path] 是否存在
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
|
/files/chunkupload:
|
||||||
|
post:
|
||||||
|
description: 分片上传文件
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: formData
|
||||||
|
name: file
|
||||||
|
required: true
|
||||||
|
type: file
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: ChunkUpload file
|
||||||
|
tags:
|
||||||
|
- File
|
||||||
/files/compress:
|
/files/compress:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -5202,6 +5318,33 @@ paths:
|
|||||||
formatEN: Download file [name]
|
formatEN: Download file [name]
|
||||||
formatZH: 下载文件 [name]
|
formatZH: 下载文件 [name]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
|
/files/download/bypath:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 下载指定文件
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.FilePath'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Download file with path
|
||||||
|
tags:
|
||||||
|
- File
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- path
|
||||||
|
formatEN: Download file [path]
|
||||||
|
formatZH: 下载文件 [path]
|
||||||
|
paramKeys: []
|
||||||
/files/loadfile:
|
/files/loadfile:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -6853,15 +6996,22 @@ paths:
|
|||||||
paramKeys: []
|
paramKeys: []
|
||||||
/settings/upgrade:
|
/settings/upgrade:
|
||||||
get:
|
get:
|
||||||
description: 系统更新信息
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 获取版本 release notes
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/dto.Upgrade'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: OK
|
description: OK
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/dto.UpgradeInfo'
|
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
summary: Load upgrade info
|
summary: Load release notes by version
|
||||||
tags:
|
tags:
|
||||||
- System Setting
|
- System Setting
|
||||||
post:
|
post:
|
||||||
@@ -7840,6 +7990,39 @@ paths:
|
|||||||
summary: Page website ssl
|
summary: Page website ssl
|
||||||
tags:
|
tags:
|
||||||
- Website SSL
|
- Website SSL
|
||||||
|
/websites/ssl/update:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 更新 ssl
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.WebsiteSSLUpdate'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Update ssl
|
||||||
|
tags:
|
||||||
|
- Website SSL
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions:
|
||||||
|
- db: website_ssls
|
||||||
|
input_colume: id
|
||||||
|
input_value: id
|
||||||
|
isList: false
|
||||||
|
output_colume: primary_domain
|
||||||
|
output_value: domain
|
||||||
|
bodyKeys:
|
||||||
|
- id
|
||||||
|
formatEN: Update ssl config [domain]
|
||||||
|
formatZH: 更新证书设置 [domain]
|
||||||
|
paramKeys: []
|
||||||
/websites/ssl/website/:websiteId:
|
/websites/ssl/website/:websiteId:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
BIN
cmd/server/web/favicon.png
Normal file
BIN
cmd/server/web/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@@ -87,6 +87,7 @@ declare module 'vue' {
|
|||||||
SvgIcon: typeof import('./src/components/svg-icon/svg-icon.vue')['default']
|
SvgIcon: typeof import('./src/components/svg-icon/svg-icon.vue')['default']
|
||||||
SystemUpgrade: typeof import('./src/components/system-upgrade/index.vue')['default']
|
SystemUpgrade: typeof import('./src/components/system-upgrade/index.vue')['default']
|
||||||
TableSetting: typeof import('./src/components/table-setting/index.vue')['default']
|
TableSetting: typeof import('./src/components/table-setting/index.vue')['default']
|
||||||
|
Tooltip: typeof import('./src/components/tooltip/index.vue')['default']
|
||||||
Upload: typeof import('./src/components/upload/index.vue')['default']
|
Upload: typeof import('./src/components/upload/index.vue')['default']
|
||||||
VCharts: typeof import('./src/components/v-charts/index.vue')['default']
|
VCharts: typeof import('./src/components/v-charts/index.vue')['default']
|
||||||
}
|
}
|
||||||
|
27
frontend/package-lock.json
generated
27
frontend/package-lock.json
generated
@@ -30,7 +30,6 @@
|
|||||||
"sass-loader": "^13.0.2",
|
"sass-loader": "^13.0.2",
|
||||||
"screenfull": "^6.0.2",
|
"screenfull": "^6.0.2",
|
||||||
"unplugin-vue-define-options": "^0.7.3",
|
"unplugin-vue-define-options": "^0.7.3",
|
||||||
"vite-plugin-monaco-editor": "^1.1.0",
|
|
||||||
"vue": "^3.2.25",
|
"vue": "^3.2.25",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-codemirror": "^6.1.1",
|
"vue-codemirror": "^6.1.1",
|
||||||
@@ -10274,14 +10273,6 @@
|
|||||||
"entities": "^2.0.0"
|
"entities": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite-plugin-monaco-editor": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vite-plugin-monaco-editor/-/vite-plugin-monaco-editor-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==",
|
|
||||||
"peerDependencies": {
|
|
||||||
"monaco-editor": ">=0.33.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/vite-plugin-vue-setup-extend": {
|
"node_modules/vite-plugin-vue-setup-extend": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz",
|
||||||
@@ -10643,9 +10634,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.75.0",
|
"version": "5.76.1",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz",
|
||||||
"integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
|
"integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
"@types/eslint-scope": "^3.7.3",
|
||||||
@@ -18367,12 +18358,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vite-plugin-monaco-editor": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/vite-plugin-monaco-editor/-/vite-plugin-monaco-editor-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==",
|
|
||||||
"requires": {}
|
|
||||||
},
|
|
||||||
"vite-plugin-vue-setup-extend": {
|
"vite-plugin-vue-setup-extend": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz",
|
||||||
@@ -18679,9 +18664,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"version": "5.75.0",
|
"version": "5.76.1",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.1.tgz",
|
||||||
"integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==",
|
"integrity": "sha512-4+YIK4Abzv8172/SGqObnUjaIHjLEuUasz9EwQj/9xmPPkYJy2Mh03Q/lJfSD3YLzbxy5FeTq5Uw0323Oh6SJQ==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
"@types/eslint-scope": "^3.7.3",
|
||||||
|
@@ -42,7 +42,6 @@
|
|||||||
"sass-loader": "^13.0.2",
|
"sass-loader": "^13.0.2",
|
||||||
"screenfull": "^6.0.2",
|
"screenfull": "^6.0.2",
|
||||||
"unplugin-vue-define-options": "^0.7.3",
|
"unplugin-vue-define-options": "^0.7.3",
|
||||||
"vite-plugin-monaco-editor": "^1.1.0",
|
|
||||||
"vue": "^3.2.25",
|
"vue": "^3.2.25",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-codemirror": "^6.1.1",
|
"vue-codemirror": "^6.1.1",
|
||||||
|
@@ -163,5 +163,7 @@ export namespace App {
|
|||||||
key: string;
|
key: string;
|
||||||
rule: string;
|
rule: string;
|
||||||
type: string;
|
type: string;
|
||||||
|
values?: any;
|
||||||
|
showValue?: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,6 @@ export namespace Login {
|
|||||||
export interface MFALoginForm {
|
export interface MFALoginForm {
|
||||||
name: string;
|
name: string;
|
||||||
password: string;
|
password: string;
|
||||||
secret: string;
|
|
||||||
code: string;
|
code: string;
|
||||||
authMethod: string;
|
authMethod: string;
|
||||||
}
|
}
|
||||||
@@ -17,7 +16,6 @@ export namespace Login {
|
|||||||
name: string;
|
name: string;
|
||||||
token: string;
|
token: string;
|
||||||
mfaStatus: string;
|
mfaStatus: string;
|
||||||
mfaSecret: string;
|
|
||||||
}
|
}
|
||||||
export interface InitUser {
|
export interface InitUser {
|
||||||
name: string;
|
name: string;
|
||||||
|
@@ -43,7 +43,8 @@ export namespace Container {
|
|||||||
state: string;
|
state: string;
|
||||||
runTime: string;
|
runTime: string;
|
||||||
|
|
||||||
isFromCompose: string;
|
isFromApp: boolean;
|
||||||
|
isFromCompose: boolean;
|
||||||
}
|
}
|
||||||
export interface ContainerStats {
|
export interface ContainerStats {
|
||||||
cpuPercent: number;
|
cpuPercent: number;
|
||||||
|
@@ -82,6 +82,7 @@ export namespace Setting {
|
|||||||
}
|
}
|
||||||
export interface UpgradeInfo {
|
export interface UpgradeInfo {
|
||||||
newVersion: string;
|
newVersion: string;
|
||||||
|
latestVersion: string;
|
||||||
releaseNote: string;
|
releaseNote: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -79,17 +79,6 @@ export namespace Website {
|
|||||||
content: string;
|
content: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Group extends CommonModel {
|
|
||||||
name: string;
|
|
||||||
default: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GroupOp {
|
|
||||||
name: string;
|
|
||||||
id?: number;
|
|
||||||
default: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Domain {
|
export interface Domain {
|
||||||
websiteId: number;
|
websiteId: number;
|
||||||
port: number;
|
port: number;
|
||||||
@@ -160,6 +149,7 @@ export namespace Website {
|
|||||||
startDate: string;
|
startDate: string;
|
||||||
provider: string;
|
provider: string;
|
||||||
websites?: Website.Website[];
|
websites?: Website.Website[];
|
||||||
|
autoRenew: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SSLCreate {
|
export interface SSLCreate {
|
||||||
@@ -179,6 +169,11 @@ export namespace Website {
|
|||||||
SSLId: number;
|
SSLId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SSLUpdate {
|
||||||
|
id: number;
|
||||||
|
autoRenew: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AcmeAccount extends CommonModel {
|
export interface AcmeAccount extends CommonModel {
|
||||||
email: string;
|
email: string;
|
||||||
url: string;
|
url: string;
|
||||||
|
@@ -6,10 +6,10 @@ export const searchContainer = (params: Container.ContainerSearch) => {
|
|||||||
return http.post<ResPage<Container.ContainerInfo>>(`/containers/search`, params);
|
return http.post<ResPage<Container.ContainerInfo>>(`/containers/search`, params);
|
||||||
};
|
};
|
||||||
export const createContainer = (params: Container.ContainerCreate) => {
|
export const createContainer = (params: Container.ContainerCreate) => {
|
||||||
return http.post(`/containers`, params);
|
return http.post(`/containers`, params, 1200000);
|
||||||
};
|
};
|
||||||
export const logContainer = (params: Container.ContainerLogSearch) => {
|
export const logContainer = (params: Container.ContainerLogSearch) => {
|
||||||
return http.post<string>(`/containers/search/log`, params);
|
return http.post<string>(`/containers/search/log`, params, 400000);
|
||||||
};
|
};
|
||||||
export const ContainerStats = (id: string) => {
|
export const ContainerStats = (id: string) => {
|
||||||
return http.get<Container.ContainerStats>(`/containers/stats/${id}`);
|
return http.get<Container.ContainerStats>(`/containers/stats/${id}`);
|
||||||
@@ -38,10 +38,10 @@ export const imagePush = (params: Container.ImagePush) => {
|
|||||||
return http.post<string>(`/containers/image/push`, params);
|
return http.post<string>(`/containers/image/push`, params);
|
||||||
};
|
};
|
||||||
export const imageLoad = (params: Container.ImageLoad) => {
|
export const imageLoad = (params: Container.ImageLoad) => {
|
||||||
return http.post(`/containers/image/load`, params);
|
return http.post(`/containers/image/load`, params, 1200000);
|
||||||
};
|
};
|
||||||
export const imageSave = (params: Container.ImageSave) => {
|
export const imageSave = (params: Container.ImageSave) => {
|
||||||
return http.post(`/containers/image/save`, params);
|
return http.post(`/containers/image/save`, params, 1200000);
|
||||||
};
|
};
|
||||||
export const imageTag = (params: Container.ImageTag) => {
|
export const imageTag = (params: Container.ImageTag) => {
|
||||||
return http.post(`/containers/image/tag`, params);
|
return http.post(`/containers/image/tag`, params);
|
||||||
@@ -117,13 +117,16 @@ export const searchCompose = (params: SearchWithPage) => {
|
|||||||
return http.post<ResPage<Container.ComposeInfo>>(`/containers/compose/search`, params);
|
return http.post<ResPage<Container.ComposeInfo>>(`/containers/compose/search`, params);
|
||||||
};
|
};
|
||||||
export const upCompose = (params: Container.ComposeCreate) => {
|
export const upCompose = (params: Container.ComposeCreate) => {
|
||||||
return http.post(`/containers/compose`, params);
|
return http.post<string>(`/containers/compose`, params);
|
||||||
|
};
|
||||||
|
export const testCompose = (params: Container.ComposeCreate) => {
|
||||||
|
return http.post<boolean>(`/containers/compose/test`, params);
|
||||||
};
|
};
|
||||||
export const composeOperator = (params: Container.ComposeOpration) => {
|
export const composeOperator = (params: Container.ComposeOpration) => {
|
||||||
return http.post(`/containers/compose/operate`, params);
|
return http.post(`/containers/compose/operate`, params);
|
||||||
};
|
};
|
||||||
export const composeUpdate = (params: Container.ComposeUpdate) => {
|
export const composeUpdate = (params: Container.ComposeUpdate) => {
|
||||||
return http.post(`/containers/compose/update`, params);
|
return http.post(`/containers/compose/update`, params, 600000);
|
||||||
};
|
};
|
||||||
|
|
||||||
// docker
|
// docker
|
||||||
|
@@ -31,7 +31,7 @@ export const updateStatus = (params: Cronjob.UpdateStatus) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const download = (params: Cronjob.Download) => {
|
export const download = (params: Cronjob.Download) => {
|
||||||
return http.download<BlobPart>(`cronjobs/download`, params, { responseType: 'blob' });
|
return http.post<string>(`cronjobs/download`, params);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const handleOnce = (id: number) => {
|
export const handleOnce = (id: number) => {
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
import http from '@/api';
|
import http from '@/api';
|
||||||
|
import { deepCopy } from '@/utils/util';
|
||||||
|
import { Base64 } from 'js-base64';
|
||||||
import { SearchWithPage, ResPage, DescriptionUpdate } from '../interface';
|
import { SearchWithPage, ResPage, DescriptionUpdate } from '../interface';
|
||||||
import { Database } from '../interface/database';
|
import { Database } from '../interface/database';
|
||||||
|
|
||||||
@@ -7,13 +9,21 @@ export const searchMysqlDBs = (params: SearchWithPage) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const addMysqlDB = (params: Database.MysqlDBCreate) => {
|
export const addMysqlDB = (params: Database.MysqlDBCreate) => {
|
||||||
return http.post(`/databases`, params);
|
let reqest = deepCopy(params) as Database.MysqlDBCreate;
|
||||||
|
if (reqest.password) {
|
||||||
|
reqest.password = Base64.encode(reqest.password);
|
||||||
|
}
|
||||||
|
return http.post(`/databases`, reqest);
|
||||||
};
|
};
|
||||||
export const updateMysqlAccess = (params: Database.ChangeInfo) => {
|
export const updateMysqlAccess = (params: Database.ChangeInfo) => {
|
||||||
return http.post(`/databases/change/access`, params);
|
return http.post(`/databases/change/access`, params);
|
||||||
};
|
};
|
||||||
export const updateMysqlPassword = (params: Database.ChangeInfo) => {
|
export const updateMysqlPassword = (params: Database.ChangeInfo) => {
|
||||||
return http.post(`/databases/change/password`, params);
|
let reqest = deepCopy(params) as Database.ChangeInfo;
|
||||||
|
if (reqest.value) {
|
||||||
|
reqest.value = Base64.encode(reqest.value);
|
||||||
|
}
|
||||||
|
return http.post(`/databases/change/password`, reqest);
|
||||||
};
|
};
|
||||||
export const updateMysqlDescription = (params: DescriptionUpdate) => {
|
export const updateMysqlDescription = (params: DescriptionUpdate) => {
|
||||||
return http.post(`/databases/description/update`, params);
|
return http.post(`/databases/description/update`, params);
|
||||||
@@ -58,7 +68,11 @@ export const redisPersistenceConf = () => {
|
|||||||
return http.get<Database.RedisPersistenceConf>(`/databases/redis/persistence/conf`);
|
return http.get<Database.RedisPersistenceConf>(`/databases/redis/persistence/conf`);
|
||||||
};
|
};
|
||||||
export const changeRedisPassword = (params: Database.ChangeInfo) => {
|
export const changeRedisPassword = (params: Database.ChangeInfo) => {
|
||||||
return http.post(`/databases/redis/password`, params);
|
let reqest = deepCopy(params) as Database.ChangeInfo;
|
||||||
|
if (reqest.value) {
|
||||||
|
reqest.value = Base64.encode(reqest.value);
|
||||||
|
}
|
||||||
|
return http.post(`/databases/redis/password`, reqest);
|
||||||
};
|
};
|
||||||
export const updateRedisPersistenceConf = (params: Database.RedisConfPersistenceUpdate) => {
|
export const updateRedisPersistenceConf = (params: Database.RedisConfPersistenceUpdate) => {
|
||||||
return http.post(`/databases/redis/persistence/update`, params);
|
return http.post(`/databases/redis/persistence/update`, params);
|
||||||
|
@@ -79,6 +79,10 @@ export const DownloadFile = (params: File.FileDownload) => {
|
|||||||
return http.download<BlobPart>('files/download', params, { responseType: 'blob', timeout: 20000 });
|
return http.download<BlobPart>('files/download', params, { responseType: 'blob', timeout: 20000 });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const DownloadByPath = (path: string) => {
|
||||||
|
return http.download<BlobPart>('files/download/bypath', { path: path }, { responseType: 'blob', timeout: 40000 });
|
||||||
|
};
|
||||||
|
|
||||||
export const ComputeDirSize = (params: File.DirSizeReq) => {
|
export const ComputeDirSize = (params: File.DirSizeReq) => {
|
||||||
return http.post<File.DirSizeRes>('files/size', params);
|
return http.post<File.DirSizeRes>('files/size', params);
|
||||||
};
|
};
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user