mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-10-09 16:00:29 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0128cd3138 | ||
|
|
157d3093f8 | ||
|
|
4ca188973e | ||
|
|
f387d89a45 | ||
|
|
54567db22f | ||
|
|
2bee68dd40 | ||
|
|
e2b6ea5253 | ||
|
|
9974c5fa20 | ||
|
|
997b706d8a | ||
|
|
3f26412585 | ||
|
|
ac99d77fbb | ||
|
|
4f6f7632f5 | ||
|
|
f74248f0d7 | ||
|
|
bb8a15ca56 | ||
|
|
52432002c7 | ||
|
|
3fade48f8f | ||
|
|
fc81801c4c | ||
|
|
c23c5b2859 | ||
|
|
ccec57e32d | ||
|
|
56ae5fbf70 | ||
|
|
735b44856e | ||
|
|
1f6ea9f494 | ||
|
|
afa643519f | ||
|
|
1767b84026 | ||
|
|
e855e7692e | ||
|
|
94d37eb68a | ||
|
|
e10b19bcde | ||
|
|
e9192e75ea | ||
|
|
2fa4f68b1e | ||
|
|
08f53a4a37 | ||
|
|
c522295c56 | ||
|
|
7a45548387 | ||
|
|
810ea9c421 | ||
|
|
ba6a4fe6d7 | ||
|
|
4d144f7a8e | ||
|
|
45c41184c1 | ||
|
|
5c29c5e7dd | ||
|
|
4da9a84363 | ||
|
|
22d8fb7867 | ||
|
|
c7058cb3e6 | ||
|
|
e6092b2658 | ||
|
|
ae19b72e61 | ||
|
|
da117582d6 | ||
|
|
c7ca1ccbd7 | ||
|
|
911b5c406d | ||
|
|
71ed4b946a | ||
|
|
4ef9fcde59 | ||
|
|
7889b5ad69 | ||
|
|
be6d3ea337 | ||
|
|
64fd715973 | ||
|
|
315f99a03a | ||
|
|
7e1351c543 | ||
|
|
bd3c829653 | ||
|
|
4f6dde02d2 | ||
|
|
8cc7d1f67f | ||
|
|
2bbba9d755 | ||
|
|
e9e4755348 | ||
|
|
9fbb63df95 | ||
|
|
5b5a649589 | ||
|
|
79556affbd | ||
|
|
9cba19d4db | ||
|
|
4f377c04b8 | ||
|
|
763df5606b | ||
|
|
e1d20e3ec9 | ||
|
|
215c082a04 | ||
|
|
984985e650 | ||
|
|
249b3c3245 | ||
|
|
725786d6aa | ||
|
|
2edddaf487 | ||
|
|
49cbab08c1 | ||
|
|
a75df66151 | ||
|
|
43e9c13c5e | ||
|
|
5ad06f121b | ||
|
|
0eaaf7aacb | ||
|
|
dd44fdd1f2 | ||
|
|
669855de70 | ||
|
|
193ae2b7d6 | ||
|
|
af4b23e0e0 | ||
|
|
c35991315d | ||
|
|
9aa852370c | ||
|
|
8f18497551 | ||
|
|
4c59951e8c | ||
|
|
eb2a80d216 | ||
|
|
41d0175a6d | ||
|
|
2f6aa0f45b | ||
|
|
17c685bc4c |
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"ansible.python.interpreterPath": "/opt/homebrew/bin/python3"
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -125,4 +125,4 @@ enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
https://www.contributor-covenant.org/translations.
|
||||
|
||||
@@ -296,7 +296,7 @@ func (b *BaseApi) SaveContent(c *gin.Context) {
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /files/upload [post]
|
||||
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传文件 [path]","formatEN":"Upload file [path]"}
|
||||
// @x-panel-log {"bodyKeys":["path", "file"],"paramKeys":[],"BeforeFunctions":[],"formatZH":"上传文件 [path]/[file]","formatEN":"Upload file [path]/[file]"}
|
||||
func (b *BaseApi) UploadFiles(c *gin.Context) {
|
||||
form, err := c.MultipartForm()
|
||||
if err != nil {
|
||||
|
||||
@@ -98,20 +98,20 @@ func (b *BaseApi) CreateRepo(c *gin.Context) {
|
||||
// @Tags Container Image-repo
|
||||
// @Summary Delete image repo
|
||||
// @Accept json
|
||||
// @Param request body dto.ImageRepoDelete true "request"
|
||||
// @Param request body dto.OperateByID true "request"
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /containers/repo/del [post]
|
||||
// @x-panel-log {"bodyKeys":["ids"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"ids","isList":true,"db":"image_repos","output_column":"name","output_value":"names"}],"formatZH":"删除镜像仓库 [names]","formatEN":"delete image repo [names]"}
|
||||
// @x-panel-log {"bodyKeys":["id"],"paramKeys":[],"BeforeFunctions":[{"input_column":"id","input_value":"id","isList":false,"db":"image_repos","output_column":"name","output_value":"name"}],"formatZH":"删除镜像仓库 [name]","formatEN":"delete image repo [name]"}
|
||||
func (b *BaseApi) DeleteRepo(c *gin.Context) {
|
||||
var req dto.ImageRepoDelete
|
||||
var req dto.OperateByID
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := imageRepoService.BatchDelete(req); err != nil {
|
||||
if err := imageRepoService.Delete(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -535,3 +535,23 @@ func (b *BaseApi) GetPHPContainerConfig(c *gin.Context) {
|
||||
}
|
||||
helper.SuccessWithData(c, data)
|
||||
}
|
||||
|
||||
// @Tags Runtime
|
||||
// @Summary Update runtime remark
|
||||
// @Accept json
|
||||
// @Param request body request.RuntimeRemarkUpdate true "request"
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Security Timestamp
|
||||
// @Router /runtimes/remark [post]
|
||||
func (b *BaseApi) UpdateRuntimeRemark(c *gin.Context) {
|
||||
var req request.RuntimeRemark
|
||||
if err := helper.CheckBindAndValidate(&req, c); err != nil {
|
||||
return
|
||||
}
|
||||
if err := runtimeService.UpdateRemark(req); err != nil {
|
||||
helper.InternalServer(c, err)
|
||||
return
|
||||
}
|
||||
helper.Success(c)
|
||||
}
|
||||
|
||||
+30
-21
@@ -29,27 +29,34 @@ type CronjobOperate struct {
|
||||
ContainerName string `json:"containerName"`
|
||||
User string `json:"user"`
|
||||
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
SnapshotRule SnapshotRule `json:"snapshotRule"`
|
||||
|
||||
SourceAccountIDs string `json:"sourceAccountIDs"`
|
||||
DownloadAccountID uint `json:"downloadAccountID"`
|
||||
RetainCopies int `json:"retainCopies" validate:"number,min=1"`
|
||||
RetryTimes int `json:"retryTimes" validate:"number,min=0"`
|
||||
Timeout uint `json:"timeout" validate:"number,min=1"`
|
||||
IgnoreErr bool `json:"ignoreErr"`
|
||||
Secret string `json:"secret"`
|
||||
|
||||
AlertCount uint `json:"alertCount"`
|
||||
AlertTitle string `json:"alertTitle"`
|
||||
}
|
||||
|
||||
type SnapshotRule struct {
|
||||
WithImage bool `json:"withImage"`
|
||||
IgnoreAppIDs []uint `json:"ignoreAppIDs"`
|
||||
}
|
||||
|
||||
type CronjobUpdateStatus struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Status string `json:"status" validate:"required"`
|
||||
@@ -87,18 +94,20 @@ type CronjobInfo struct {
|
||||
ContainerName string `json:"containerName"`
|
||||
User string `json:"user"`
|
||||
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
RetainCopies int `json:"retainCopies"`
|
||||
RetryTimes int `json:"retryTimes"`
|
||||
Timeout uint `json:"timeout"`
|
||||
ScriptID uint `json:"scriptID"`
|
||||
AppID string `json:"appID"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBType string `json:"dbType"`
|
||||
DBName string `json:"dbName"`
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
RetainCopies int `json:"retainCopies"`
|
||||
RetryTimes int `json:"retryTimes"`
|
||||
Timeout uint `json:"timeout"`
|
||||
IgnoreErr bool `json:"ignoreErr"`
|
||||
SnapshotRule SnapshotRule `json:"snapshotRule"`
|
||||
|
||||
SourceAccounts []string `json:"sourceAccounts"`
|
||||
DownloadAccount string `json:"downloadAccount"`
|
||||
|
||||
@@ -6,8 +6,8 @@ type ImageRepoCreate struct {
|
||||
Name string `json:"name" validate:"required"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ type ImageRepoUpdate struct {
|
||||
ID uint `json:"id"`
|
||||
DownloadUrl string `json:"downloadUrl"`
|
||||
Protocol string `json:"protocol"`
|
||||
Username string `json:"username" validate:"max=256"`
|
||||
Password string `json:"password" validate:"max=256"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Auth bool `json:"auth"`
|
||||
}
|
||||
|
||||
|
||||
@@ -92,11 +92,12 @@ type FileWget struct {
|
||||
}
|
||||
|
||||
type FileMove struct {
|
||||
Type string `json:"type" validate:"required"`
|
||||
OldPaths []string `json:"oldPaths" validate:"required"`
|
||||
NewPath string `json:"newPath" validate:"required"`
|
||||
Name string `json:"name"`
|
||||
Cover bool `json:"cover"`
|
||||
Type string `json:"type" validate:"required"`
|
||||
OldPaths []string `json:"oldPaths" validate:"required"`
|
||||
NewPath string `json:"newPath" validate:"required"`
|
||||
Name string `json:"name"`
|
||||
Cover bool `json:"cover"`
|
||||
CoverPaths []string `json:"coverPaths"`
|
||||
}
|
||||
|
||||
type FileDownload struct {
|
||||
|
||||
@@ -12,15 +12,17 @@ type RuntimeSearch struct {
|
||||
}
|
||||
|
||||
type RuntimeCreate struct {
|
||||
AppDetailID uint `json:"appDetailId"`
|
||||
Name string `json:"name"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Resource string `json:"resource"`
|
||||
Image string `json:"image"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
AppDetailID uint `json:"appDetailId"`
|
||||
Name string `json:"name"`
|
||||
Resource string `json:"resource"`
|
||||
Image string `json:"image"`
|
||||
Type string `json:"type"`
|
||||
Version string `json:"version"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
Remark string `json:"remark"`
|
||||
|
||||
Params map[string]interface{} `json:"params"`
|
||||
NodeConfig
|
||||
}
|
||||
|
||||
@@ -53,14 +55,16 @@ type RuntimeDelete struct {
|
||||
}
|
||||
|
||||
type RuntimeUpdate struct {
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
Params map[string]interface{} `json:"params"`
|
||||
Image string `json:"image"`
|
||||
Version string `json:"version"`
|
||||
Rebuild bool `json:"rebuild"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
Image string `json:"image"`
|
||||
Version string `json:"version"`
|
||||
Rebuild bool `json:"rebuild"`
|
||||
Source string `json:"source"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
Remark string `json:"remark"`
|
||||
|
||||
Params map[string]interface{} `json:"params"`
|
||||
NodeConfig
|
||||
}
|
||||
|
||||
@@ -131,3 +135,8 @@ type PHPContainerConfig struct {
|
||||
Environments []Environment `json:"environments"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
}
|
||||
|
||||
type RuntimeRemark struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ type WebsiteCreate struct {
|
||||
TaskID string `json:"taskID"`
|
||||
ParentWebsiteID uint `json:"parentWebsiteID"`
|
||||
|
||||
SiteDir string `json:"siteDir"`
|
||||
|
||||
RuntimeConfig
|
||||
FtpConfig
|
||||
DataBaseConfig
|
||||
|
||||
@@ -53,6 +53,7 @@ type ExistFileInfo struct {
|
||||
Path string `json:"path"`
|
||||
Size int64 `json:"size"`
|
||||
ModTime time.Time `json:"modTime"`
|
||||
IsDir bool `json:"isDir"`
|
||||
}
|
||||
|
||||
type UserInfo struct {
|
||||
|
||||
@@ -30,6 +30,7 @@ type RuntimeDTO struct {
|
||||
Volumes []request.Volume `json:"volumes"`
|
||||
ContainerStatus string `json:"containerStatus"`
|
||||
Container string `json:"container"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
type PackageScripts struct {
|
||||
@@ -53,6 +54,7 @@ func NewRuntimeDTO(runtime model.Runtime) RuntimeDTO {
|
||||
Port: runtime.Port,
|
||||
Path: runtime.GetPath(),
|
||||
Container: runtime.ContainerName,
|
||||
Remark: runtime.Remark,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ type SettingInfo struct {
|
||||
AppStoreSyncStatus string `json:"appStoreSyncStatus"`
|
||||
|
||||
FileRecycleBin string `json:"fileRecycleBin"`
|
||||
|
||||
SnapshotIgnore string `json:"snapshotIgnore"`
|
||||
}
|
||||
|
||||
type SettingUpdate struct {
|
||||
|
||||
@@ -23,11 +23,14 @@ type SnapshotCreate struct {
|
||||
BackupData []DataTree `json:"backupData"`
|
||||
PanelData []DataTree `json:"panelData"`
|
||||
|
||||
WithDockerConf bool `json:"withDockerConf"`
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
|
||||
IgnoreFiles []string `json:"ignoreFiles"`
|
||||
}
|
||||
|
||||
type SnapshotData struct {
|
||||
@@ -35,11 +38,13 @@ type SnapshotData struct {
|
||||
BackupData []DataTree `json:"backupData"`
|
||||
PanelData []DataTree `json:"panelData"`
|
||||
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
WithDockerConf bool `json:"withDockerConf"`
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
IgnoreFiles []string `json:"ignoreFiles"`
|
||||
}
|
||||
type DataTree struct {
|
||||
ID string `json:"id"`
|
||||
|
||||
@@ -29,12 +29,14 @@ type Cronjob struct {
|
||||
URL string `json:"url"`
|
||||
IsDir bool `json:"isDir"`
|
||||
SourceDir string `json:"sourceDir"`
|
||||
SnapshotRule string `json:"snapshotRule"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
|
||||
SourceAccountIDs string `json:"sourceAccountIDs"`
|
||||
DownloadAccountID uint `json:"downloadAccountID"`
|
||||
RetryTimes uint `json:"retryTimes"`
|
||||
Timeout uint `json:"timeout"`
|
||||
IgnoreErr bool `json:"ignoreErr"`
|
||||
RetainCopies uint64 `json:"retainCopies"`
|
||||
|
||||
Status string `json:"status"`
|
||||
|
||||
@@ -23,6 +23,7 @@ type Runtime struct {
|
||||
Message string `json:"message"`
|
||||
CodeDir string `json:"codeDir"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Remark string `json:"remark"`
|
||||
}
|
||||
|
||||
func (r *Runtime) GetComposePath() string {
|
||||
|
||||
@@ -15,14 +15,17 @@ type Snapshot struct {
|
||||
TaskRecoverID string `json:"taskRecoverID"`
|
||||
TaskRollbackID string `json:"taskRollbackID"`
|
||||
|
||||
AppData string `json:"appData"`
|
||||
PanelData string `json:"panelData"`
|
||||
BackupData string `json:"backupData"`
|
||||
AppData string `json:"appData"`
|
||||
PanelData string `json:"panelData"`
|
||||
BackupData string `json:"backupData"`
|
||||
|
||||
WithDockerConf bool `json:"withDockerConf"`
|
||||
WithMonitorData bool `json:"withMonitorData"`
|
||||
WithLoginLog bool `json:"withLoginLog"`
|
||||
WithOperationLog bool `json:"withOperationLog"`
|
||||
WithSystemLog bool `json:"withSystemLog"`
|
||||
WithTaskLog bool `json:"withTaskLog"`
|
||||
IgnoreFiles string `json:"ignoreFiles"`
|
||||
|
||||
InterruptStep string `json:"interruptStep"`
|
||||
RecoverStatus string `json:"recoverStatus"`
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -15,28 +14,25 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/env"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
||||
"github.com/joho/godotenv"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/compose"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/env"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type AppInstallService struct {
|
||||
@@ -124,7 +120,7 @@ func (a *AppInstallService) Page(req request.AppInstalledSearch) (int64, []respo
|
||||
}
|
||||
}
|
||||
|
||||
installDTOs, err := handleInstalled(installs, req.Update, req.Sync)
|
||||
installDTOs, _ := handleInstalled(installs, req.Update, req.Sync)
|
||||
if req.Update {
|
||||
total = int64(len(installDTOs))
|
||||
}
|
||||
@@ -635,10 +631,14 @@ func (a *AppInstallService) DeleteCheck(installID uint) ([]dto.AppResource, erro
|
||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithLinkId(appInstall.ID), repo.WithByFrom(constant.AppResourceLocal))
|
||||
for _, resource := range resources {
|
||||
linkInstall, _ := appInstallRepo.GetFirst(repo.WithByID(resource.AppInstallId))
|
||||
res = append(res, dto.AppResource{
|
||||
Type: "app",
|
||||
Name: linkInstall.Name,
|
||||
})
|
||||
if linkInstall.ID > 0 {
|
||||
res = append(res, dto.AppResource{
|
||||
Type: "app",
|
||||
Name: linkInstall.Name,
|
||||
})
|
||||
} else {
|
||||
_ = appInstallResourceRepo.DeleteBy(context.Background(), appInstallResourceRepo.WithAppInstallId(resource.AppInstallId))
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
+66
-104
@@ -5,7 +5,6 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
@@ -19,39 +18,33 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/api/v2/helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||
"github.com/subosito/gotenv"
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/env"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/compose"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||
composeV2 "github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/env"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
|
||||
"github.com/compose-spec/compose-go/v2/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/subosito/gotenv"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type DatabaseOp string
|
||||
@@ -386,21 +379,25 @@ func deleteAppInstall(deleteReq request.AppInstallDelete) error {
|
||||
}
|
||||
|
||||
resources, _ := appInstallResourceRepo.GetBy(appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
if deleteReq.DeleteDB && len(resources) > 0 {
|
||||
del := dto.DelAppLink{
|
||||
Ctx: ctx,
|
||||
Install: &install,
|
||||
ForceDelete: deleteReq.ForceDelete,
|
||||
Task: uninstallTask,
|
||||
}
|
||||
t.LogWithOps(task.TaskDelete, i18n.GetMsgByKey("Database"))
|
||||
if err = deleteLink(del); err != nil {
|
||||
t.LogFailedWithOps(task.TaskDelete, i18n.GetMsgByKey("Database"), err)
|
||||
if !deleteReq.ForceDelete {
|
||||
return err
|
||||
if len(resources) > 0 {
|
||||
if deleteReq.DeleteDB {
|
||||
del := dto.DelAppLink{
|
||||
Ctx: ctx,
|
||||
Install: &install,
|
||||
ForceDelete: deleteReq.ForceDelete,
|
||||
Task: uninstallTask,
|
||||
}
|
||||
t.LogWithOps(task.TaskDelete, i18n.GetMsgByKey("Database"))
|
||||
if err = deleteLink(del); err != nil {
|
||||
t.LogFailedWithOps(task.TaskDelete, i18n.GetMsgByKey("Database"), err)
|
||||
if !deleteReq.ForceDelete {
|
||||
return err
|
||||
}
|
||||
}
|
||||
t.LogSuccessWithOps(task.TaskDelete, i18n.GetMsgByKey("Database"))
|
||||
} else {
|
||||
_ = appInstallResourceRepo.DeleteBy(ctx, appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
}
|
||||
t.LogSuccessWithOps(task.TaskDelete, i18n.GetMsgByKey("Database"))
|
||||
}
|
||||
|
||||
if DatabaseKeys[install.App.Key] > 0 {
|
||||
@@ -489,17 +486,14 @@ func deleteLink(del dto.DelAppLink) error {
|
||||
return appInstallResourceRepo.DeleteBy(del.Ctx, appInstallResourceRepo.WithAppInstallId(install.ID))
|
||||
}
|
||||
|
||||
func getUpgradeCompose(install model.AppInstall, detail model.AppDetail) (string, error) {
|
||||
if detail.DockerCompose == "" {
|
||||
return "", nil
|
||||
}
|
||||
func handleUpgradeCompose(install model.AppInstall, detail model.AppDetail) (map[string]interface{}, error) {
|
||||
composeMap := make(map[string]interface{})
|
||||
if err := yaml.Unmarshal([]byte(detail.DockerCompose), &composeMap); err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
value, ok := composeMap["services"]
|
||||
if !ok || value == nil {
|
||||
return "", buserr.New("ErrFileParse")
|
||||
return nil, buserr.New("ErrFileParse")
|
||||
}
|
||||
servicesMap := value.(map[string]interface{})
|
||||
if len(servicesMap) == 1 {
|
||||
@@ -517,6 +511,34 @@ func getUpgradeCompose(install model.AppInstall, detail model.AppDetail) (string
|
||||
delete(servicesMap, oldServiceName)
|
||||
}
|
||||
}
|
||||
serviceValue := servicesMap[install.ServiceName].(map[string]interface{})
|
||||
|
||||
oldComposeMap := make(map[string]interface{})
|
||||
if err := yaml.Unmarshal([]byte(install.DockerCompose), &oldComposeMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oldValue, ok := oldComposeMap["services"]
|
||||
if !ok || oldValue == nil {
|
||||
return nil, buserr.New("ErrFileParse")
|
||||
}
|
||||
oldValueMap := oldValue.(map[string]interface{})
|
||||
oldServiceValue := oldValueMap[install.ServiceName].(map[string]interface{})
|
||||
if oldServiceValue["deploy"] != nil {
|
||||
serviceValue["deploy"] = oldServiceValue["deploy"]
|
||||
}
|
||||
servicesMap[install.ServiceName] = serviceValue
|
||||
composeMap["services"] = servicesMap
|
||||
return composeMap, nil
|
||||
}
|
||||
|
||||
func getUpgradeCompose(install model.AppInstall, detail model.AppDetail) (string, error) {
|
||||
if detail.DockerCompose == "" {
|
||||
return "", nil
|
||||
}
|
||||
composeMap, err := handleUpgradeCompose(install, detail)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
envs := make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(install.Env), &envs); err != nil {
|
||||
return "", err
|
||||
@@ -617,7 +639,7 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dockerCLi, err := docker.NewClient()
|
||||
dockerCLi, _ := docker.NewClient()
|
||||
if req.PullImage {
|
||||
images, err := composeV2.GetDockerComposeImagesV2(content, []byte(detail.DockerCompose))
|
||||
if err != nil {
|
||||
@@ -674,63 +696,6 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
||||
}
|
||||
envParams := make(map[string]string, len(envs))
|
||||
handleMap(envs, envParams)
|
||||
if install.App.Key == "openresty" && install.App.Resource == "remote" && !common.CompareVersion(install.Version, "1.25.3.2-0-1") {
|
||||
t.Log(i18n.GetMsgByKey("MoveSiteDir"))
|
||||
siteDir := path.Join(global.Dir.DataDir, "www")
|
||||
envParams["WEBSITE_DIR"] = siteDir
|
||||
oldSiteDir := path.Join(install.GetPath(), "www")
|
||||
t.Log(i18n.GetWithName("MoveSiteToDir", siteDir))
|
||||
if err := fileOp.CopyDir(oldSiteDir, global.Dir.DataDir); err != nil {
|
||||
t.Log(i18n.GetMsgByKey("ErrMoveSiteDir"))
|
||||
return err
|
||||
}
|
||||
newConfDir := path.Join(global.Dir.DataDir, "www", "conf.d")
|
||||
_ = fileOp.CreateDir(newConfDir, constant.DirPerm)
|
||||
oldConfDir := path.Join(install.GetPath(), "conf/conf.d")
|
||||
items, err := os.ReadDir(oldConfDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range items {
|
||||
itemPath := path.Join(oldConfDir, item.Name())
|
||||
if item.IsDir() {
|
||||
_ = fileOp.Mv(itemPath, newConfDir)
|
||||
}
|
||||
if item.Name() != "default.conf" && item.Name() != "00.default.conf" {
|
||||
_ = fileOp.Mv(itemPath, newConfDir)
|
||||
}
|
||||
}
|
||||
nginxConfPath := path.Join(install.GetPath(), "conf", "nginx.conf")
|
||||
parse, err := parser.NewParser(nginxConfPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config, err := parse.Parse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.FilePath = nginxConfPath
|
||||
httpDirective := config.FindHttp()
|
||||
httpDirective.UpdateDirective("include", []string{"/usr/local/openresty/nginx/conf/default/*.conf"})
|
||||
|
||||
if err = nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return buserr.WithErr("ErrUpdateBuWebsite", err)
|
||||
}
|
||||
t.Log(i18n.GetMsgByKey("DeleteRuntimePHP"))
|
||||
_ = fileOp.DeleteDir(path.Join(global.Dir.RuntimeDir, "php"))
|
||||
websites, _ := websiteRepo.List(repo.WithByType("runtime"))
|
||||
for _, website := range websites {
|
||||
runtime, _ := runtimeRepo.GetFirst(context.Background(), repo.WithByID(website.RuntimeID))
|
||||
if runtime != nil && runtime.Type == "php" {
|
||||
website.Type = constant.Static
|
||||
website.RuntimeID = 0
|
||||
_ = websiteRepo.SaveWithoutCtx(&website)
|
||||
}
|
||||
}
|
||||
_ = runtimeRepo.DeleteBy(repo.WithByType("php"))
|
||||
t.Log(i18n.GetMsgByKey("MoveSiteDirSuccess"))
|
||||
}
|
||||
|
||||
if err = env.Write(envParams, install.GetEnvPath()); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1802,10 +1767,7 @@ func ignoreUpdate(installed model.AppInstall) bool {
|
||||
return true
|
||||
}
|
||||
ignores, _ := appIgnoreUpgradeRepo.List(appDetailRepo.WithAppId(installed.AppId), appIgnoreUpgradeRepo.WithScope("all"))
|
||||
if len(ignores) > 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return len(ignores) > 0
|
||||
}
|
||||
|
||||
func RequestDownloadCallBack(downloadCallBackUrl string) {
|
||||
|
||||
@@ -290,8 +290,6 @@ func (u *BackupService) RefreshToken(req dto.OperateByID) error {
|
||||
switch backup.Type {
|
||||
case constant.OneDrive:
|
||||
refreshToken, err = client.RefreshToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.GoogleDrive:
|
||||
refreshToken, err = client.RefreshGoogleToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.ALIYUN:
|
||||
refreshToken, err = client.RefreshALIToken(varMap)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
@@ -194,7 +193,7 @@ func (u *BackupRecordService) ListFiles(req dto.OperateByID) []string {
|
||||
var datas []string
|
||||
for _, file := range files {
|
||||
fileName := path.Base(file)
|
||||
if len(file) != 0 && (strings.HasPrefix(fileName, "1panel-v2.") || strings.HasPrefix(fileName, "snapshot-1panel-v2.")) {
|
||||
if len(file) != 0 && checkSnapshotIsOk(fileName) {
|
||||
datas = append(datas, path.Base(file))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,10 +639,7 @@ func handleAlert(stdout, clamName string, clamId uint) {
|
||||
EntryID: clamId,
|
||||
Param: strconv.Itoa(infectedFiles),
|
||||
}
|
||||
err := xpack.PushAlert(pushAlert)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("clamdscan push failed, err: %v", err)
|
||||
}
|
||||
_ = xpack.PushAlert(pushAlert)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
@@ -94,8 +94,8 @@ func NewIContainerService() IContainerService {
|
||||
|
||||
func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, error) {
|
||||
var (
|
||||
records []types.Container
|
||||
list []types.Container
|
||||
records []container.Summary
|
||||
list []container.Summary
|
||||
)
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
@@ -165,7 +165,7 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
||||
|
||||
total, start, end := len(list), (req.Page-1)*req.PageSize, req.Page*req.PageSize
|
||||
if start > total {
|
||||
records = make([]types.Container, 0)
|
||||
records = make([]container.Summary, 0)
|
||||
} else {
|
||||
if end >= total {
|
||||
end = total
|
||||
@@ -307,7 +307,7 @@ func (u *ContainerService) ContainerListStats() ([]dto.ContainerListStats, error
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(list))
|
||||
for i := 0; i < len(list); i++ {
|
||||
go func(item types.Container) {
|
||||
go func(item container.Summary) {
|
||||
datas = append(datas, loadCpuAndMem(client, item.ID))
|
||||
wg.Done()
|
||||
}(list[i])
|
||||
@@ -466,7 +466,7 @@ func (u *ContainerService) Prune(req dto.ContainerPrune) (dto.ContainerPruneRepo
|
||||
report.DeletedNumber = len(rep.VolumesDeleted)
|
||||
report.SpaceReclaimed = int(rep.SpaceReclaimed)
|
||||
case "buildcache":
|
||||
opts := types.BuildCachePruneOptions{}
|
||||
opts := build.CachePruneOptions{}
|
||||
opts.All = true
|
||||
rep, err := client.BuildCachePrune(context.Background(), opts)
|
||||
if err != nil {
|
||||
@@ -915,9 +915,6 @@ func collectLogs(done <-chan struct{}, params dto.StreamLog, messageChan chan<-
|
||||
defer close(messageChan)
|
||||
defer close(errorChan)
|
||||
var cmdArgs []string
|
||||
if params.Type == "compose" {
|
||||
cmdArgs = []string{"compose", "-f", params.Compose}
|
||||
}
|
||||
cmdArgs = append(cmdArgs, "logs")
|
||||
if params.Follow {
|
||||
cmdArgs = append(cmdArgs, "-f")
|
||||
@@ -932,7 +929,20 @@ func collectLogs(done <-chan struct{}, params dto.StreamLog, messageChan chan<-
|
||||
cmdArgs = append(cmdArgs, params.Container)
|
||||
}
|
||||
|
||||
dockerCmd := exec.Command("docker", cmdArgs...)
|
||||
var dockerCmd *exec.Cmd
|
||||
if params.Type == "compose" {
|
||||
dockerComposCmd := common.GetDockerComposeCommand()
|
||||
if dockerComposCmd == "docker-compose" {
|
||||
newCmdArgs := append([]string{"-f", params.Compose}, cmdArgs...)
|
||||
dockerCmd = exec.Command(dockerComposCmd, newCmdArgs...)
|
||||
} else {
|
||||
newCmdArgs := append([]string{"compose", "-f", params.Compose}, cmdArgs...)
|
||||
dockerCmd = exec.Command("docker", newCmdArgs...)
|
||||
}
|
||||
} else {
|
||||
dockerCmd = exec.Command("docker", cmdArgs...)
|
||||
}
|
||||
|
||||
dockerCmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
stdout, err := dockerCmd.StdoutPipe()
|
||||
@@ -958,7 +968,7 @@ func collectLogs(done <-chan struct{}, params dto.StreamLog, messageChan chan<-
|
||||
}
|
||||
}()
|
||||
|
||||
scanner := bufio.NewScanner(stdout)
|
||||
reader := bufio.NewReader(stdout)
|
||||
|
||||
processKilled := false
|
||||
go func() {
|
||||
@@ -972,19 +982,30 @@ func collectLogs(done <-chan struct{}, params dto.StreamLog, messageChan chan<-
|
||||
}
|
||||
}()
|
||||
|
||||
for scanner.Scan() {
|
||||
message := scanner.Text()
|
||||
for {
|
||||
line, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
if len(line) > 0 {
|
||||
line = strings.TrimSuffix(line, "\n")
|
||||
select {
|
||||
case messageChan <- line:
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
errorChan <- fmt.Errorf("reader error: %v", err)
|
||||
return
|
||||
}
|
||||
line = strings.TrimSuffix(line, "\n")
|
||||
select {
|
||||
case messageChan <- message:
|
||||
case messageChan <- line:
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = scanner.Err(); err != nil && err != io.EOF {
|
||||
errorChan <- fmt.Errorf("scanner error: %v", err)
|
||||
}
|
||||
|
||||
_ = dockerCmd.Wait()
|
||||
}
|
||||
|
||||
@@ -1300,7 +1321,7 @@ func checkPortStats(ports []dto.PortHelper) (nat.PortMap, error) {
|
||||
return portMap, nil
|
||||
}
|
||||
|
||||
func loadConfigInfo(isCreate bool, req dto.ContainerOperate, oldContainer *types.ContainerJSON) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) {
|
||||
func loadConfigInfo(isCreate bool, req dto.ContainerOperate, oldContainer *container.InspectResponse) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) {
|
||||
var config container.Config
|
||||
var hostConf container.HostConfig
|
||||
if !isCreate {
|
||||
@@ -1383,7 +1404,7 @@ func loadConfigInfo(isCreate bool, req dto.ContainerOperate, oldContainer *types
|
||||
return &config, &hostConf, &networkConf, nil
|
||||
}
|
||||
|
||||
func reCreateAfterUpdate(name string, client *client.Client, config *container.Config, hostConf *container.HostConfig, networkConf *types.NetworkSettings) {
|
||||
func reCreateAfterUpdate(name string, client *client.Client, config *container.Config, hostConf *container.HostConfig, networkConf *container.NetworkSettings) {
|
||||
ctx := context.Background()
|
||||
|
||||
var oldNetworkConf network.NetworkingConfig
|
||||
@@ -1405,7 +1426,7 @@ func reCreateAfterUpdate(name string, client *client.Client, config *container.C
|
||||
global.LOG.Info("recreate after container update successful")
|
||||
}
|
||||
|
||||
func loadVolumeBinds(binds []types.MountPoint) []dto.VolumeHelper {
|
||||
func loadVolumeBinds(binds []container.MountPoint) []dto.VolumeHelper {
|
||||
var datas []dto.VolumeHelper
|
||||
for _, bind := range binds {
|
||||
var volumeItem dto.VolumeHelper
|
||||
@@ -1425,13 +1446,13 @@ func loadVolumeBinds(binds []types.MountPoint) []dto.VolumeHelper {
|
||||
return datas
|
||||
}
|
||||
|
||||
func loadPortByInspect(id string, client *client.Client) ([]types.Port, error) {
|
||||
container, err := client.ContainerInspect(context.Background(), id)
|
||||
func loadPortByInspect(id string, client *client.Client) ([]container.Port, error) {
|
||||
containerItem, err := client.ContainerInspect(context.Background(), id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var itemPorts []types.Port
|
||||
for key, val := range container.ContainerJSONBase.HostConfig.PortBindings {
|
||||
var itemPorts []container.Port
|
||||
for key, val := range containerItem.ContainerJSONBase.HostConfig.PortBindings {
|
||||
if !strings.Contains(string(key), "/") {
|
||||
continue
|
||||
}
|
||||
@@ -1440,15 +1461,15 @@ func loadPortByInspect(id string, client *client.Client) ([]types.Port, error) {
|
||||
|
||||
for _, itemVal := range val {
|
||||
publicPort, _ := strconv.ParseUint(itemVal.HostPort, 10, 16)
|
||||
itemPorts = append(itemPorts, types.Port{PrivatePort: uint16(itemPort), Type: item[1], PublicPort: uint16(publicPort), IP: itemVal.HostIP})
|
||||
itemPorts = append(itemPorts, container.Port{PrivatePort: uint16(itemPort), Type: item[1], PublicPort: uint16(publicPort), IP: itemVal.HostIP})
|
||||
}
|
||||
}
|
||||
return itemPorts, nil
|
||||
}
|
||||
func transPortToStr(ports []types.Port) []string {
|
||||
func transPortToStr(ports []container.Port) []string {
|
||||
var (
|
||||
ipv4Ports []types.Port
|
||||
ipv6Ports []types.Port
|
||||
ipv4Ports []container.Port
|
||||
ipv6Ports []container.Port
|
||||
)
|
||||
for _, port := range ports {
|
||||
if strings.Contains(port.IP, ":") {
|
||||
@@ -1461,7 +1482,7 @@ func transPortToStr(ports []types.Port) []string {
|
||||
list2 := simplifyPort(ipv6Ports)
|
||||
return append(list1, list2...)
|
||||
}
|
||||
func simplifyPort(ports []types.Port) []string {
|
||||
func simplifyPort(ports []container.Port) []string {
|
||||
var datas []string
|
||||
if len(ports) == 0 {
|
||||
return datas
|
||||
@@ -1557,7 +1578,7 @@ func loadComposeCount(client *client.Client) int {
|
||||
|
||||
return len(composeMap)
|
||||
}
|
||||
func loadContainerPortForInfo(itemPorts []types.Port) []dto.PortHelper {
|
||||
func loadContainerPortForInfo(itemPorts []container.Port) []dto.PortHelper {
|
||||
var exposedPorts []dto.PortHelper
|
||||
samePortMap := make(map[string]dto.PortHelper)
|
||||
ports := transPortToStr(itemPorts)
|
||||
|
||||
@@ -73,6 +73,9 @@ func (u *CronjobService) SearchWithPage(search dto.PageCronjob) (int64, interfac
|
||||
} else {
|
||||
item.AlertCount = 0
|
||||
}
|
||||
if cronjob.Type == "snapshot" && len(cronjob.SnapshotRule) != 0 {
|
||||
_ = json.Unmarshal([]byte(cronjob.SnapshotRule), &item.SnapshotRule)
|
||||
}
|
||||
dtoCronjobs = append(dtoCronjobs, item)
|
||||
}
|
||||
return total, dtoCronjobs, err
|
||||
@@ -94,6 +97,9 @@ func (u *CronjobService) LoadInfo(req dto.OperateByID) (*dto.CronjobOperate, err
|
||||
} else {
|
||||
item.AlertCount = 0
|
||||
}
|
||||
if cronjob.Type == "snapshot" && len(cronjob.SnapshotRule) != 0 {
|
||||
_ = json.Unmarshal([]byte(cronjob.SnapshotRule), &item.SnapshotRule)
|
||||
}
|
||||
return &item, err
|
||||
}
|
||||
|
||||
@@ -279,6 +285,13 @@ func (u *CronjobService) Create(req dto.CronjobOperate) error {
|
||||
if err := copier.Copy(&cronjob, &req); err != nil {
|
||||
return buserr.WithDetail("ErrStructTransform", err.Error(), nil)
|
||||
}
|
||||
if cronjob.Type == "snapshot" {
|
||||
rule, err := json.Marshal(req.SnapshotRule)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cronjob.SnapshotRule = string(rule)
|
||||
}
|
||||
if cronjob.Type == "cutWebsiteLog" {
|
||||
backupAccount, err := backupRepo.Get(repo.WithByType(constant.Local))
|
||||
if backupAccount.ID == 0 {
|
||||
@@ -372,6 +385,13 @@ func (u *CronjobService) Update(id uint, req dto.CronjobOperate) error {
|
||||
if err := copier.Copy(&cronjob, &req); err != nil {
|
||||
return buserr.WithDetail("ErrStructTransform", err.Error(), nil)
|
||||
}
|
||||
if req.Type == "snapshot" {
|
||||
itemRule, err := json.Marshal(req.SnapshotRule)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cronjob.SnapshotRule = string(itemRule)
|
||||
}
|
||||
cronModel, err := cronjobRepo.Get(repo.WithByID(id))
|
||||
if err != nil {
|
||||
return buserr.New("ErrRecordNotFound")
|
||||
@@ -412,12 +432,14 @@ func (u *CronjobService) Update(id uint, req dto.CronjobOperate) error {
|
||||
upMap["db_name"] = req.DBName
|
||||
upMap["url"] = req.URL
|
||||
upMap["source_dir"] = req.SourceDir
|
||||
upMap["snapshot_rule"] = cronjob.SnapshotRule
|
||||
|
||||
upMap["source_account_ids"] = req.SourceAccountIDs
|
||||
upMap["download_account_id"] = req.DownloadAccountID
|
||||
upMap["retain_copies"] = req.RetainCopies
|
||||
upMap["retry_times"] = req.RetryTimes
|
||||
upMap["timeout"] = req.Timeout
|
||||
upMap["ignore_err"] = req.IgnoreErr
|
||||
upMap["secret"] = req.Secret
|
||||
err = cronjobRepo.Update(id, upMap)
|
||||
if err != nil {
|
||||
|
||||
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@@ -47,6 +48,7 @@ func (u *CronjobService) handleApp(cronjob model.Cronjob, startTime time.Time, t
|
||||
return err
|
||||
}
|
||||
for _, app := range apps {
|
||||
retry := 0
|
||||
taskItem.AddSubTaskWithOps(task.GetTaskName(app.Name, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error {
|
||||
var record model.BackupRecord
|
||||
record.From = "cronjob"
|
||||
@@ -58,11 +60,22 @@ func (u *CronjobService) handleApp(cronjob model.Cronjob, startTime time.Time, t
|
||||
backupDir := path.Join(global.Dir.TmpDir, fmt.Sprintf("app/%s/%s", app.App.Key, app.Name))
|
||||
record.FileName = fmt.Sprintf("app_%s_%s.tar.gz", app.Name, startTime.Format(constant.DateTimeSlimLayout)+common.RandStrAndNum(5))
|
||||
if err := doAppBackup(&app, task, backupDir, record.FileName, cronjob.ExclusionRules, cronjob.Secret); err != nil {
|
||||
return err
|
||||
if retry < int(cronjob.RetryTimes) || !cronjob.IgnoreErr {
|
||||
retry++
|
||||
return err
|
||||
} else {
|
||||
task.Log(i18n.GetMsgWithDetail("IgnoreBackupErr", err.Error()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
downloadPath, err := u.uploadCronjobBackFile(cronjob, task, accountMap, path.Join(backupDir, record.FileName))
|
||||
if err != nil {
|
||||
return err
|
||||
if retry < int(cronjob.RetryTimes) || !cronjob.IgnoreErr {
|
||||
retry++
|
||||
return err
|
||||
}
|
||||
task.Log(i18n.GetMsgWithDetail("IgnoreUploadErr", err.Error()))
|
||||
return nil
|
||||
}
|
||||
record.FileDir = path.Dir(downloadPath)
|
||||
if err := backupRepo.CreateRecord(&record); err != nil {
|
||||
@@ -86,6 +99,7 @@ func (u *CronjobService) handleWebsite(cronjob model.Cronjob, startTime time.Tim
|
||||
return err
|
||||
}
|
||||
for _, web := range webs {
|
||||
retry := 0
|
||||
taskItem.AddSubTaskWithOps(task.GetTaskName(web.Alias, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error {
|
||||
var record model.BackupRecord
|
||||
record.From = "cronjob"
|
||||
@@ -98,12 +112,23 @@ func (u *CronjobService) handleWebsite(cronjob model.Cronjob, startTime time.Tim
|
||||
record.FileName = fmt.Sprintf("website_%s_%s.tar.gz", web.Alias, startTime.Format(constant.DateTimeSlimLayout)+common.RandStrAndNum(5))
|
||||
|
||||
if err := doWebsiteBackup(&web, taskItem, backupDir, record.FileName, cronjob.ExclusionRules, cronjob.Secret); err != nil {
|
||||
return err
|
||||
if retry < int(cronjob.RetryTimes) || !cronjob.IgnoreErr {
|
||||
retry++
|
||||
return err
|
||||
} else {
|
||||
task.Log(i18n.GetMsgWithDetail("IgnoreBackupErr", err.Error()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
downloadPath, err := u.uploadCronjobBackFile(cronjob, task, accountMap, path.Join(backupDir, record.FileName))
|
||||
if err != nil {
|
||||
return err
|
||||
if retry < int(cronjob.RetryTimes) || !cronjob.IgnoreErr {
|
||||
retry++
|
||||
return err
|
||||
}
|
||||
task.Log(i18n.GetMsgWithDetail("IgnoreUploadErr", err.Error()))
|
||||
return nil
|
||||
}
|
||||
record.FileDir = path.Dir(downloadPath)
|
||||
if err := backupRepo.CreateRecord(&record); err != nil {
|
||||
@@ -127,6 +152,7 @@ func (u *CronjobService) handleDatabase(cronjob model.Cronjob, startTime time.Ti
|
||||
return err
|
||||
}
|
||||
for _, dbInfo := range dbs {
|
||||
retry := 0
|
||||
itemName := fmt.Sprintf("%s[%s] - %s", dbInfo.Database, dbInfo.DBType, dbInfo.Name)
|
||||
taskItem.AddSubTaskWithOps(task.GetTaskName(itemName, task.TaskBackup, task.TaskScopeCronjob), func(task *task.Task) error {
|
||||
var record model.BackupRecord
|
||||
@@ -141,17 +167,34 @@ func (u *CronjobService) handleDatabase(cronjob model.Cronjob, startTime time.Ti
|
||||
record.FileName = fmt.Sprintf("db_%s_%s.sql.gz", dbInfo.Name, startTime.Format(constant.DateTimeSlimLayout)+common.RandStrAndNum(5))
|
||||
if cronjob.DBType == "mysql" || cronjob.DBType == "mariadb" {
|
||||
if err := doMysqlBackup(dbInfo, backupDir, record.FileName); err != nil {
|
||||
return err
|
||||
if retry < int(cronjob.RetryTimes) || !cronjob.IgnoreErr {
|
||||
retry++
|
||||
return err
|
||||
} else {
|
||||
task.Log(i18n.GetMsgWithDetail("IgnoreBackupErr", err.Error()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := doPostgresqlgBackup(dbInfo, backupDir, record.FileName); err != nil {
|
||||
return err
|
||||
if retry < int(cronjob.RetryTimes) || !cronjob.IgnoreErr {
|
||||
retry++
|
||||
return err
|
||||
} else {
|
||||
task.Log(i18n.GetMsgWithDetail("IgnoreBackupErr", err.Error()))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
downloadPath, err := u.uploadCronjobBackFile(cronjob, task, accountMap, path.Join(backupDir, record.FileName))
|
||||
if err != nil {
|
||||
return err
|
||||
if retry < int(cronjob.RetryTimes) || !cronjob.IgnoreErr {
|
||||
retry++
|
||||
return err
|
||||
}
|
||||
task.Log(i18n.GetMsgWithDetail("IgnoreUploadErr", err.Error()))
|
||||
return nil
|
||||
}
|
||||
record.FileDir = path.Dir(downloadPath)
|
||||
if err := backupRepo.CreateRecord(&record); err != nil {
|
||||
@@ -250,10 +293,6 @@ func (u *CronjobService) handleSnapshot(cronjob model.Cronjob, jobRecord model.J
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
itemData, err := NewISnapshotService().LoadSnapshotData()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var record model.BackupRecord
|
||||
record.From = "cronjob"
|
||||
@@ -268,6 +307,11 @@ func (u *CronjobService) handleSnapshot(cronjob model.Cronjob, jobRecord model.J
|
||||
if !global.IsMaster {
|
||||
scope = "agent"
|
||||
}
|
||||
|
||||
itemData, err := loadSnapWithRule(cronjob)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := dto.SnapshotCreate{
|
||||
Name: fmt.Sprintf("snapshot-1panel-%s-%s-linux-%s-%s", scope, versionItem.Value, loadOs(), jobRecord.StartTime.Format(constant.DateTimeSlimLayout)+common.RandStrAndNum(5)),
|
||||
Secret: cronjob.Secret,
|
||||
@@ -278,11 +322,13 @@ func (u *CronjobService) handleSnapshot(cronjob model.Cronjob, jobRecord model.J
|
||||
AppData: itemData.AppData,
|
||||
PanelData: itemData.PanelData,
|
||||
BackupData: itemData.BackupData,
|
||||
WithDockerConf: true,
|
||||
WithMonitorData: true,
|
||||
WithLoginLog: true,
|
||||
WithOperationLog: true,
|
||||
WithSystemLog: true,
|
||||
WithTaskLog: true,
|
||||
IgnoreFiles: strings.Split(cronjob.ExclusionRules, ","),
|
||||
}
|
||||
|
||||
if err := NewISnapshotService().SnapshotCreate(taskItem, req, jobRecord.ID, cronjob.RetryTimes, cronjob.Timeout); err != nil {
|
||||
@@ -451,3 +497,52 @@ func handleBackupLogs(taskItem *task.Task, targetDir, fileName string, secret st
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadSnapWithRule(cronjob model.Cronjob) (dto.SnapshotData, error) {
|
||||
itemData, err := NewISnapshotService().LoadSnapshotData()
|
||||
if err != nil {
|
||||
return itemData, err
|
||||
}
|
||||
|
||||
if len(cronjob.SnapshotRule) == 0 {
|
||||
return itemData, nil
|
||||
}
|
||||
var snapRule dto.SnapshotRule
|
||||
if err := json.Unmarshal([]byte(cronjob.SnapshotRule), &snapRule); err != nil {
|
||||
return itemData, err
|
||||
}
|
||||
if len(snapRule.IgnoreAppIDs) == 0 && !snapRule.WithImage {
|
||||
return itemData, nil
|
||||
}
|
||||
|
||||
var ignoreApps []model.AppInstall
|
||||
if len(snapRule.IgnoreAppIDs) != 0 {
|
||||
ignoreApps, _ = appInstallRepo.ListBy(context.Background(), repo.WithByIDs(snapRule.IgnoreAppIDs))
|
||||
}
|
||||
if len(ignoreApps) == 0 && !snapRule.WithImage {
|
||||
return itemData, nil
|
||||
}
|
||||
for i := 0; i < len(itemData.AppData); i++ {
|
||||
isIgnore := false
|
||||
for _, ignore := range ignoreApps {
|
||||
if ignore.App.Key == itemData.AppData[i].Key && ignore.Name == itemData.AppData[i].Name {
|
||||
isIgnore = true
|
||||
itemData.AppData[i].IsCheck = false
|
||||
for j := 0; j < len(itemData.AppData[i].Children); j++ {
|
||||
if itemData.AppData[i].Children[j].Label == "appData" {
|
||||
itemData.AppData[i].Children[j].IsCheck = false
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if snapRule.WithImage && !isIgnore {
|
||||
for j := 0; j < len(itemData.AppData[i].Children); j++ {
|
||||
if itemData.AppData[i].Children[j].Label == "appImage" {
|
||||
itemData.AppData[i].Children[j].IsCheck = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return itemData, nil
|
||||
}
|
||||
|
||||
@@ -271,6 +271,10 @@ func (u *CronjobService) uploadCronjobBackFile(cronjob model.Cronjob, task *task
|
||||
cloudSrc := strings.TrimPrefix(file, global.Dir.TmpDir+"/")
|
||||
for _, account := range accounts {
|
||||
if len(account) != 0 {
|
||||
task.LogStart(i18n.GetMsgWithMap("UploadFile", map[string]interface{}{
|
||||
"file": pathUtils.Join(accountMap[account].backupPath, cloudSrc),
|
||||
"backup": accountMap[account].name,
|
||||
}))
|
||||
_, err := accountMap[account].client.Upload(file, pathUtils.Join(accountMap[account].backupPath, cloudSrc))
|
||||
task.LogWithStatus(
|
||||
i18n.GetMsgWithMap("UploadFile", map[string]interface{}{
|
||||
@@ -355,9 +359,5 @@ func handleCronJobAlert(cronjob *model.Cronjob) {
|
||||
EntryID: cronjob.ID,
|
||||
Param: cronjob.Type,
|
||||
}
|
||||
err := xpack.PushAlert(pushAlert)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("cronjob alert push failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
_ = xpack.PushAlert(pushAlert)
|
||||
}
|
||||
|
||||
@@ -390,10 +390,10 @@ type diskInfo struct {
|
||||
func loadDiskInfo() []dto.DiskInfo {
|
||||
var datas []dto.DiskInfo
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(2 * time.Second))
|
||||
stdout, err := cmdMgr.RunWithStdoutBashC("df -hT -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")
|
||||
stdout, err := cmdMgr.RunWithStdoutBashC("timeout 2 df -hT -P | awk 'NR>1 && !/tmpfs|snap\\/core|udev/ {print}'")
|
||||
if err != nil {
|
||||
cmdMgr2 := cmd.NewCommandMgr(cmd.WithTimeout(1 * time.Second))
|
||||
stdout, err = cmdMgr2.RunWithStdoutBashC("df -lhT -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")
|
||||
stdout, err = cmdMgr2.RunWithStdoutBashC("timeout 1 df -lhT -P | awk 'NR>1 && !/tmpfs|snap\\/core|udev/ {print}'")
|
||||
if err != nil {
|
||||
return datas
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ func (u *DeviceService) Update(key, value string) error {
|
||||
if err := ntp.UpdateSystemTimeZone(value); err != nil {
|
||||
return err
|
||||
}
|
||||
go common.RestartService(true, true, false)
|
||||
go common.RestartService(global.IsMaster, true, false)
|
||||
case "DNS":
|
||||
if err := updateDNS(strings.Split(value, ",")); err != nil {
|
||||
return err
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
@@ -663,7 +664,7 @@ func dropBuildCache() {
|
||||
if err != nil {
|
||||
global.LOG.Errorf("do not get docker client")
|
||||
}
|
||||
opts := types.BuildCachePruneOptions{}
|
||||
opts := build.CachePruneOptions{}
|
||||
opts.All = true
|
||||
_, err = client.BuildCachePrune(context.Background(), opts)
|
||||
if err != nil {
|
||||
|
||||
@@ -220,16 +220,6 @@ func (u *DockerService) UpdateConf(req dto.SettingUpdate, withRestart bool) erro
|
||||
daemonMap["proxies"] = proxies
|
||||
}
|
||||
}
|
||||
if len(daemonMap) == 0 {
|
||||
if len(file) == 0 {
|
||||
return nil
|
||||
}
|
||||
_ = os.Remove(constant.DaemonJsonPath)
|
||||
if withRestart {
|
||||
return restartDocker()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
newJson, err := json.MarshalIndent(daemonMap, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -277,11 +267,6 @@ func (u *DockerService) UpdateLogOption(req dto.LogOption) error {
|
||||
_ = json.Unmarshal(file, &daemonMap)
|
||||
|
||||
changeLogOption(daemonMap, req.LogMaxFile, req.LogMaxSize)
|
||||
if len(daemonMap) == 0 {
|
||||
_ = os.Remove(constant.DaemonJsonPath)
|
||||
_ = restartDocker()
|
||||
return nil
|
||||
}
|
||||
newJson, err := json.MarshalIndent(daemonMap, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -321,11 +306,6 @@ func (u *DockerService) UpdateIpv6Option(req dto.Ipv6Option) error {
|
||||
if req.Experimental {
|
||||
daemonMap["experimental"] = req.Experimental
|
||||
}
|
||||
if len(daemonMap) == 0 {
|
||||
_ = os.Remove(constant.DaemonJsonPath)
|
||||
_ = restartDocker()
|
||||
return nil
|
||||
}
|
||||
newJson, err := json.MarshalIndent(daemonMap, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -345,13 +325,6 @@ func (u *DockerService) UpdateIpv6Option(req dto.Ipv6Option) error {
|
||||
}
|
||||
|
||||
func (u *DockerService) UpdateConfByFile(req dto.DaemonJsonUpdateByFile) error {
|
||||
if len(req.File) == 0 {
|
||||
_ = os.Remove(constant.DaemonJsonPath)
|
||||
if err := restartDocker(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err := createIfNotExistDaemonJsonFile()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+28
-15
@@ -4,7 +4,10 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/jinzhu/copier"
|
||||
"golang.org/x/text/encoding"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
@@ -15,9 +18,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"golang.org/x/net/html/charset"
|
||||
"golang.org/x/sys/unix"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/transform"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
@@ -335,17 +334,22 @@ func (f *FileService) GetContent(op request.FileContentReq) (response.FileInfo,
|
||||
if len(content) > 1024 {
|
||||
content = content[:1024]
|
||||
}
|
||||
if !utf8.Valid(content) {
|
||||
_, decodeName, _ := charset.DetermineEncoding(content, "")
|
||||
if decodeName == "windows-1252" || strings.ToLower(decodeName) == "gbk" {
|
||||
reader := strings.NewReader(info.Content)
|
||||
item := transform.NewReader(reader, simplifiedchinese.GBK.NewDecoder())
|
||||
contents, err := io.ReadAll(item)
|
||||
if err != nil {
|
||||
return response.FileInfo{}, err
|
||||
}
|
||||
info.Content = string(contents)
|
||||
_, decodeName, _ := charset.DetermineEncoding(content, "")
|
||||
decoder := files.GetDecoderByName(decodeName)
|
||||
if decoder != nil {
|
||||
reader := strings.NewReader(info.Content)
|
||||
var dec *encoding.Decoder
|
||||
if decodeName == "windows-1252" {
|
||||
dec = simplifiedchinese.GBK.NewDecoder()
|
||||
} else {
|
||||
dec = decoder.NewDecoder()
|
||||
}
|
||||
decodedReader := transform.NewReader(reader, dec)
|
||||
contents, err := io.ReadAll(decodedReader)
|
||||
if err != nil {
|
||||
return response.FileInfo{}, err
|
||||
}
|
||||
info.Content = string(contents)
|
||||
}
|
||||
return response.FileInfo{FileInfo: *info}, nil
|
||||
}
|
||||
@@ -390,10 +394,18 @@ func (f *FileService) MvFile(m request.FileMove) error {
|
||||
return buserr.New("ErrMovePathFailed")
|
||||
}
|
||||
}
|
||||
var errs []error
|
||||
if m.Type == "cut" {
|
||||
if len(m.CoverPaths) > 0 {
|
||||
for _, src := range m.CoverPaths {
|
||||
if err := fo.CopyAndReName(src, m.NewPath, "", true); err != nil {
|
||||
errs = append(errs, err)
|
||||
global.LOG.Errorf("cut copy file [%s] to [%s] failed, err: %s", src, m.NewPath, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return fo.Cut(m.OldPaths, m.NewPath, m.Name, m.Cover)
|
||||
}
|
||||
var errs []error
|
||||
if m.Type == "copy" {
|
||||
for _, src := range m.OldPaths {
|
||||
if err := fo.CopyAndReName(src, m.NewPath, m.Name, m.Cover); err != nil {
|
||||
@@ -565,6 +577,7 @@ func (f *FileService) BatchCheckFiles(req request.FilePathsCheck) []response.Exi
|
||||
Name: info.Name(),
|
||||
Path: filePath,
|
||||
ModTime: info.ModTime(),
|
||||
IsDir: info.IsDir(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -602,7 +602,7 @@ func getProcessStatus(config *response.SupervisorProcessConfig, containerName st
|
||||
out, err = exec.Command("supervisorctl", processNames...).Output()
|
||||
output = string(out)
|
||||
}
|
||||
if containerName == "" && err != nil {
|
||||
if output == "" && err != nil {
|
||||
return err
|
||||
}
|
||||
lines := strings.Split(output, "\n")
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/docker"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/build"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
@@ -189,7 +189,7 @@ func (u *ImageService) ImageBuild(req dto.ImageBuild) error {
|
||||
return err
|
||||
}
|
||||
|
||||
opts := types.ImageBuildOptions{
|
||||
opts := build.ImageBuildOptions{
|
||||
Dockerfile: fileName,
|
||||
Tags: []string{req.Name},
|
||||
Remove: true,
|
||||
@@ -432,7 +432,7 @@ func formatFileSize(fileSize int64) (size string) {
|
||||
}
|
||||
}
|
||||
|
||||
func checkUsed(imageID string, containers []types.Container) bool {
|
||||
func checkUsed(imageID string, containers []container.Summary) bool {
|
||||
for _, container := range containers {
|
||||
if container.ImageID == imageID {
|
||||
return true
|
||||
|
||||
@@ -28,7 +28,7 @@ type IImageRepoService interface {
|
||||
Login(req dto.OperateByID) error
|
||||
Create(req dto.ImageRepoCreate) error
|
||||
Update(req dto.ImageRepoUpdate) error
|
||||
BatchDelete(req dto.ImageRepoDelete) error
|
||||
Delete(req dto.OperateByID) error
|
||||
}
|
||||
|
||||
func NewIImageRepoService() IImageRepoService {
|
||||
@@ -91,28 +91,7 @@ func (u *ImageRepoService) Create(req dto.ImageRepoCreate) error {
|
||||
if err := u.handleRegistries(req.DownloadUrl, "", "create"); err != nil {
|
||||
return fmt.Errorf("create registry %s failed, err: %v", req.DownloadUrl, err)
|
||||
}
|
||||
if err := restartDocker(); err != nil {
|
||||
return err
|
||||
}
|
||||
ticker := time.NewTicker(3 * time.Second)
|
||||
defer ticker.Stop()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
|
||||
if err := func() error {
|
||||
for range ticker.C {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
cancel()
|
||||
return errors.New("the docker service cannot be restarted")
|
||||
default:
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashC("systemctl is-active docker")
|
||||
if string(stdout) == "active\n" && err == nil {
|
||||
global.LOG.Info("docker restart with new conf successful!")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}(); err != nil {
|
||||
if err := stopBeforeUpdateRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -131,15 +110,32 @@ func (u *ImageRepoService) Create(req dto.ImageRepoCreate) error {
|
||||
return imageRepoRepo.Create(&imageRepo)
|
||||
}
|
||||
|
||||
func (u *ImageRepoService) BatchDelete(req dto.ImageRepoDelete) error {
|
||||
for _, id := range req.Ids {
|
||||
if id == 1 {
|
||||
return errors.New("The default value cannot be edit !")
|
||||
}
|
||||
func (u *ImageRepoService) Delete(req dto.OperateByID) error {
|
||||
if req.ID == 1 {
|
||||
return errors.New("The default value cannot be edit !")
|
||||
}
|
||||
if err := imageRepoRepo.Delete(repo.WithByIDs(req.Ids)); err != nil {
|
||||
itemRepo, _ := imageRepoRepo.Get(repo.WithByID(req.ID))
|
||||
if itemRepo.ID == 0 {
|
||||
return buserr.New("ErrRecordNotFound")
|
||||
}
|
||||
if itemRepo.Auth {
|
||||
_, _ = cmd.NewCommandMgr().RunWithStdout("docker", "logout", "-i", itemRepo.DownloadUrl)
|
||||
}
|
||||
if itemRepo.Protocol == "https" {
|
||||
return imageRepoRepo.Delete(repo.WithByID(req.ID))
|
||||
}
|
||||
if err := u.handleRegistries("", itemRepo.DownloadUrl, "delete"); err != nil {
|
||||
return fmt.Errorf("delete registry %s failed, err: %v", itemRepo.DownloadUrl, err)
|
||||
}
|
||||
if err := validateDockerConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := imageRepoRepo.Delete(repo.WithByID(req.ID)); err != nil {
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
_ = restartDocker()
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -154,38 +150,37 @@ func (u *ImageRepoService) Update(req dto.ImageRepoUpdate) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
needRestart := false
|
||||
if repo.Protocol == "http" && req.Protocol == "https" {
|
||||
if err := u.handleRegistries("", repo.DownloadUrl, "delete"); err != nil {
|
||||
return fmt.Errorf("delete registry %s failed, err: %v", repo.DownloadUrl, err)
|
||||
}
|
||||
needRestart = true
|
||||
}
|
||||
if repo.Protocol == "http" && req.Protocol == "http" {
|
||||
if err := u.handleRegistries(req.DownloadUrl, repo.DownloadUrl, "update"); err != nil {
|
||||
return fmt.Errorf("update registry %s => %s failed, err: %v", repo.DownloadUrl, req.DownloadUrl, err)
|
||||
}
|
||||
needRestart = repo.DownloadUrl == req.DownloadUrl
|
||||
}
|
||||
if repo.Protocol == "https" && req.Protocol == "http" {
|
||||
if err := u.handleRegistries(req.DownloadUrl, "", "create"); err != nil {
|
||||
return fmt.Errorf("create registry %s failed, err: %v", req.DownloadUrl, err)
|
||||
}
|
||||
needRestart = true
|
||||
}
|
||||
if repo.Auth != req.Auth || repo.DownloadUrl != req.DownloadUrl {
|
||||
if repo.Auth {
|
||||
cmdMgr := cmd.NewCommandMgr()
|
||||
_, _ = cmdMgr.RunWithStdout("docker", "logout", "-i", repo.DownloadUrl)
|
||||
}
|
||||
if req.Auth {
|
||||
if err := u.CheckConn(req.DownloadUrl, req.Username, req.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
if needRestart {
|
||||
if err := stopBeforeUpdateRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateDockerConfig(); err != nil {
|
||||
return err
|
||||
if repo.Auth {
|
||||
_, _ = cmd.NewCommandMgr().RunWithStdout("docker", "logout", "-i", repo.DownloadUrl)
|
||||
}
|
||||
if err := restartDocker(); err != nil {
|
||||
return err
|
||||
if req.Auth {
|
||||
if err := u.CheckConn(req.DownloadUrl, req.Username, req.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
upMap := make(map[string]interface{})
|
||||
@@ -260,3 +255,34 @@ func (u *ImageRepoService) handleRegistries(newHost, delHost, handle string) err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stopBeforeUpdateRepo() error {
|
||||
if err := validateDockerConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := restartDocker(); err != nil {
|
||||
return err
|
||||
}
|
||||
ticker := time.NewTicker(3 * time.Second)
|
||||
defer ticker.Stop()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||
if err := func() error {
|
||||
for range ticker.C {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
cancel()
|
||||
return errors.New("the docker service cannot be restarted")
|
||||
default:
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashC("systemctl is-active docker")
|
||||
if string(stdout) == "active\n" && err == nil {
|
||||
global.LOG.Info("docker restart with new conf successful!")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -283,11 +283,19 @@ func (m McpServerService) BindDomain(req request.McpBindDomain) error {
|
||||
}
|
||||
}
|
||||
group, _ := groupRepo.Get(groupRepo.WithByWebsiteDefault())
|
||||
|
||||
domain, err := ParseDomain(req.Domain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if domain.Port == 0 {
|
||||
domain.Port = nginxInstall.HttpPort
|
||||
}
|
||||
createWebsiteReq := request.WebsiteCreate{
|
||||
Domains: []request.WebsiteDomain{
|
||||
{
|
||||
Domain: req.Domain,
|
||||
Port: 80,
|
||||
Domain: domain.Domain,
|
||||
Port: domain.Port,
|
||||
},
|
||||
},
|
||||
Alias: strings.ToLower(req.Domain),
|
||||
|
||||
@@ -52,6 +52,7 @@ type IRuntimeService interface {
|
||||
SyncForRestart() error
|
||||
SyncRuntimeStatus() error
|
||||
DeleteCheck(installID uint) ([]dto.AppResource, error)
|
||||
UpdateRemark(req request.RuntimeRemark) error
|
||||
|
||||
GetPHPExtensions(runtimeID uint) (response.PHPExtensionRes, error)
|
||||
InstallPHPExtension(req request.PHPExtensionInstallReq) error
|
||||
@@ -108,6 +109,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||
Type: create.Type,
|
||||
Version: create.Version,
|
||||
Status: constant.StatusNormal,
|
||||
Remark: create.Remark,
|
||||
}
|
||||
return nil, runtimeRepo.Create(context.Background(), runtime)
|
||||
}
|
||||
@@ -168,6 +170,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
||||
Version: create.Version,
|
||||
ContainerName: containerName.(string),
|
||||
Port: strings.Join(hostPorts, ","),
|
||||
Remark: create.Remark,
|
||||
}
|
||||
|
||||
switch create.Type {
|
||||
@@ -454,6 +457,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||
Params: req.Params,
|
||||
CodeDir: req.CodeDir,
|
||||
Version: req.Version,
|
||||
Remark: req.Remark,
|
||||
NodeConfig: request.NodeConfig{
|
||||
Install: true,
|
||||
ExposedPorts: req.ExposedPorts,
|
||||
@@ -465,6 +469,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.Remark = req.Remark
|
||||
runtime.Env = string(envContent)
|
||||
runtime.DockerCompose = string(composeContent)
|
||||
|
||||
@@ -719,25 +724,27 @@ func (r *RuntimeService) InstallPHPExtension(req request.PHPExtensionInstallReq)
|
||||
return err
|
||||
}
|
||||
client, err := docker.NewClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer client.Close()
|
||||
if err == nil {
|
||||
oldImageID, err := client.GetImageIDByName(runtime.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = cmdMgr.RunBashCf("docker commit %s %s", runtime.ContainerName, runtime.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newImageID, err := client.GetImageIDByName(runtime.Image)
|
||||
if err == nil && newImageID != oldImageID {
|
||||
if err := client.DeleteImage(oldImageID); err != nil {
|
||||
t.Log(fmt.Sprintf("delete old image error %v", err))
|
||||
} else {
|
||||
t.Log("delete old image success")
|
||||
}
|
||||
oldImageID, err := client.GetImageIDByName(runtime.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = cmdMgr.RunBashCf("docker commit %s %s", runtime.ContainerName, runtime.Image)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newImageID, err := client.GetImageIDByName(runtime.Image)
|
||||
if err == nil && newImageID != oldImageID {
|
||||
if err := client.DeleteImage(oldImageID); err != nil {
|
||||
t.Log(fmt.Sprintf("delete old image error %v", err))
|
||||
} else {
|
||||
t.Log("delete old image success")
|
||||
}
|
||||
}
|
||||
handlePHPDir(*runtime)
|
||||
if err = restartRuntime(runtime); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -887,7 +894,6 @@ func (r *RuntimeService) UpdatePHPConfig(req request.PHPConfigUpdate) (err error
|
||||
pattern := "^" + regexp.QuoteMeta("disable_functions") + "\\s*=\\s*.*$"
|
||||
if matched, _ := regexp.MatchString(pattern, line); matched {
|
||||
lines[i] = "disable_functions" + " = " + strings.Join(req.DisableFunctions, ",")
|
||||
break
|
||||
}
|
||||
case "upload_max_filesize":
|
||||
pattern := "^" + regexp.QuoteMeta("post_max_size") + "\\s*=\\s*.*$"
|
||||
@@ -1143,3 +1149,12 @@ func (r *RuntimeService) OperateSupervisorProcessFile(req request.PHPSupervisorP
|
||||
logFile := path.Join(supervisorDir, "log", fmt.Sprintf("%s.out.log", req.SupervisorProcessFileReq.Name))
|
||||
return handleSupervisorFile(req.SupervisorProcessFileReq, configDir, runtime.ContainerName, logFile)
|
||||
}
|
||||
|
||||
func (r *RuntimeService) UpdateRemark(req request.RuntimeRemark) error {
|
||||
runtime, err := runtimeRepo.GetFirst(context.Background(), repo.WithByID(req.ID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.Remark = req.Remark
|
||||
return runtimeRepo.Save(runtime)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
cmd2 "github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -17,6 +16,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
cmd2 "github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/common"
|
||||
|
||||
@@ -89,7 +90,7 @@ func handlePHP(create request.RuntimeCreate, runtime *model.Runtime, fileOp file
|
||||
version, ok := create.Params["PHP_VERSION"]
|
||||
if ok {
|
||||
extensionsDir := path.Join(projectDir, "extensions", getExtensionDir(version.(string)))
|
||||
_ = fileOp.CreateDir(extensionsDir, 0644)
|
||||
_ = fileOp.CreateDir(extensionsDir, 0755)
|
||||
}
|
||||
|
||||
composeContent, envContent, forms, err := handleParams(create, projectDir)
|
||||
@@ -101,6 +102,13 @@ func handlePHP(create request.RuntimeCreate, runtime *model.Runtime, fileOp file
|
||||
runtime.Params = string(forms)
|
||||
runtime.Status = constant.StatusBuilding
|
||||
|
||||
go func() {
|
||||
appDetail, err := appDetailRepo.GetFirst(repo.WithByID(runtime.AppDetailID))
|
||||
if err == nil {
|
||||
RequestDownloadCallBack(appDetail.DownloadCallBackUrl)
|
||||
}
|
||||
}()
|
||||
|
||||
go buildRuntime(runtime, "", "", false)
|
||||
return
|
||||
}
|
||||
@@ -141,11 +149,27 @@ func reCreateRuntime(runtime *model.Runtime) {
|
||||
}
|
||||
}
|
||||
|
||||
func runComposeCmdWithLog(operate string, composePath string, logPath string) error {
|
||||
cmd := exec.Command("docker", "compose", "-f", composePath, operate)
|
||||
if operate == "up" {
|
||||
cmd = exec.Command("docker", "compose", "-f", composePath, operate, "-d")
|
||||
func getComposeCmd(composePath, operate string) *exec.Cmd {
|
||||
dockerCommand := global.CONF.DockerConfig.Command
|
||||
var cmd *exec.Cmd
|
||||
if dockerCommand == "docker-compose" {
|
||||
if operate == "up" {
|
||||
cmd = exec.Command("docker-compose", "-f", composePath, operate, "-d")
|
||||
} else {
|
||||
cmd = exec.Command("docker-compose", "-f", composePath, operate)
|
||||
}
|
||||
} else {
|
||||
if operate == "up" {
|
||||
cmd = exec.Command("docker", "compose", "-f", composePath, operate, "-d")
|
||||
} else {
|
||||
cmd = exec.Command("docker", "compose", "-f", composePath, operate)
|
||||
}
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runComposeCmdWithLog(operate string, composePath string, logPath string) error {
|
||||
cmd := getComposeCmd(composePath, operate)
|
||||
logFile, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, constant.FilePerm)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("Failed to open log file: %v", err)
|
||||
@@ -287,10 +311,22 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
|
||||
_ = logFile.Close()
|
||||
}()
|
||||
|
||||
newPHPVersion := getRuntimeEnv(runtime.Env, "PHP_VERSION")
|
||||
oldPHPVersion := getRuntimeEnv(oldEnv, "PHP_VERSION")
|
||||
if newPHPVersion != oldPHPVersion {
|
||||
_ = os.Rename(path.Join(runtimePath, "extensions", getExtensionDir(oldPHPVersion)), path.Join(runtimePath, "extensions", getExtensionDir(newPHPVersion)))
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Hour)
|
||||
defer cancel()
|
||||
|
||||
cmd := exec.CommandContext(ctx, "docker", "compose", "-f", composePath, "build")
|
||||
dockerCommand := global.CONF.DockerConfig.Command
|
||||
var cmd *exec.Cmd
|
||||
if dockerCommand == "docker-compose" {
|
||||
cmd = exec.CommandContext(ctx, "docker-compose", "-f", composePath, "build")
|
||||
} else {
|
||||
cmd = exec.CommandContext(ctx, "docker", "compose", "-f", composePath, "build")
|
||||
}
|
||||
cmd.Stdout = logFile
|
||||
var stderrBuf bytes.Buffer
|
||||
multiWriterStderr := io.MultiWriter(&stderrBuf, logFile)
|
||||
@@ -373,6 +409,7 @@ func buildRuntime(runtime *model.Runtime, oldImageID string, oldEnv string, rebu
|
||||
if deleteImageID != "" {
|
||||
deleteImageByID(deleteImageID, runtime.Image, client)
|
||||
}
|
||||
handlePHPDir(*runtime)
|
||||
if out, err := compose.DownAndUp(composePath); err != nil {
|
||||
runtime.Status = constant.StatusStartErr
|
||||
runtime.Message = out
|
||||
@@ -553,7 +590,7 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
|
||||
serviceName = name
|
||||
serviceValue = service.(map[string]interface{})
|
||||
delete(serviceValue, "ports")
|
||||
if create.ExposedPorts != nil && len(create.ExposedPorts) > 0 {
|
||||
if len(create.ExposedPorts) > 0 {
|
||||
var ports []interface{}
|
||||
for i, port := range create.ExposedPorts {
|
||||
containerPortStr := fmt.Sprintf("CONTAINER_PORT_%d", i)
|
||||
@@ -567,12 +604,12 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime
|
||||
create.Params[hostIPStr] = port.HostIP
|
||||
}
|
||||
if create.Type == constant.RuntimePHP {
|
||||
ports = append(ports, fmt.Sprintf("127.0.0.1:${PANEL_APP_PORT_HTTP}:9000"))
|
||||
ports = append(ports, "127.0.0.1:${PANEL_APP_PORT_HTTP}:9000")
|
||||
}
|
||||
serviceValue["ports"] = ports
|
||||
} else {
|
||||
if create.Type == constant.RuntimePHP {
|
||||
serviceValue["ports"] = []interface{}{fmt.Sprintf("127.0.0.1:${PANEL_APP_PORT_HTTP}:9000")}
|
||||
serviceValue["ports"] = []interface{}{"127.0.0.1:${PANEL_APP_PORT_HTTP}:9000"}
|
||||
}
|
||||
}
|
||||
var environments []interface{}
|
||||
@@ -959,3 +996,43 @@ func handleRuntimeDTO(res *response.RuntimeDTO, runtime model.Runtime) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handlePHPDir(runtime model.Runtime) {
|
||||
fileOp := files.NewFileOp()
|
||||
dirs := []string{
|
||||
path.Join(runtime.GetPath(), "conf"),
|
||||
path.Join(runtime.GetPath(), "extensions"),
|
||||
path.Join(runtime.GetPath(), "composer"),
|
||||
path.Join(runtime.GetPath(), "log"),
|
||||
}
|
||||
for _, dir := range dirs {
|
||||
_ = fileOp.ChmodR(dir, 0755, true)
|
||||
_ = fileOp.ChownR(dir, strconv.Itoa(1000), strconv.Itoa(1000), true)
|
||||
}
|
||||
}
|
||||
|
||||
func HandleOldPHPRuntime() {
|
||||
runtimes, _ := runtimeRepo.List(repo.WithByType(constant.RuntimePHP))
|
||||
if len(runtimes) == 0 {
|
||||
return
|
||||
}
|
||||
fileOp := files.NewFileOp()
|
||||
for _, runtime := range runtimes {
|
||||
composePtah := runtime.GetComposePath()
|
||||
composeBytes, _ := fileOp.GetContent(composePtah)
|
||||
composeContent := strings.ReplaceAll(string(composeBytes), "./conf:/usr/local/etc/php", "./conf/php.ini:/usr/local/etc/php/php.ini")
|
||||
composeContent = strings.ReplaceAll(composeContent, "./conf/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf", "./conf/php-fpm.conf:/usr/local/etc/php-fpm.conf")
|
||||
composeContent = strings.ReplaceAll(composeContent, "./extensions:${EXTENSION_DIR}", "./extensions:/usr/local/lib/php/extensions")
|
||||
_ = fileOp.WriteFile(composePtah, strings.NewReader(composeContent), constant.DirPerm)
|
||||
_ = fileOp.WriteFile(runtime.GetFPMPath(), bytes.NewReader(nginx_conf.GetWebsiteFile("php-fpm.conf")), constant.DirPerm)
|
||||
supervisorConfigPath := path.Join(runtime.GetPath(), "supervisor", "supervisor.d", "php-fpm.ini")
|
||||
supervisorConfigBytes, _ := fileOp.GetContent(supervisorConfigPath)
|
||||
if !strings.Contains(string(supervisorConfigBytes), "nodaemonize") {
|
||||
newConfigContent := strings.ReplaceAll(string(supervisorConfigBytes), "command=php-fpm", "command=php-fpm --nodaemonize")
|
||||
_ = fileOp.WriteFile(supervisorConfigPath, bytes.NewReader([]byte(newConfigContent)), constant.DirPerm)
|
||||
}
|
||||
go func() {
|
||||
_ = restartRuntime(&runtime)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ func (u *SnapshotService) SnapshotImport(req dto.SnapshotImport) error {
|
||||
}
|
||||
|
||||
for _, snapName := range req.Names {
|
||||
if !strings.HasPrefix(snapName, "1panel-v2.") && !strings.HasPrefix(snapName, "snapshot-1panel-v2.") {
|
||||
if !checkSnapshotIsOk(snapName) {
|
||||
return fmt.Errorf("incorrect snapshot name format of %s", snapName)
|
||||
}
|
||||
snap, _ := snapshotRepo.Get(repo.WithByName(strings.ReplaceAll(snapName, ".tar.gz", "")))
|
||||
@@ -77,11 +77,11 @@ func (u *SnapshotService) SnapshotImport(req dto.SnapshotImport) error {
|
||||
}
|
||||
}
|
||||
for _, snap := range req.Names {
|
||||
shortName := strings.TrimPrefix(snap, "snapshot_")
|
||||
nameItems := strings.Split(shortName, "-")
|
||||
if !strings.HasPrefix(shortName, "1panel-v") || !strings.HasSuffix(shortName, ".tar.gz") || len(nameItems) < 3 {
|
||||
return fmt.Errorf("incorrect snapshot name format of %s", shortName)
|
||||
}
|
||||
shortName := strings.ReplaceAll(snap, "snapshot-", "")
|
||||
shortName = strings.ReplaceAll(shortName, "1panel-", "")
|
||||
shortName = strings.ReplaceAll(shortName, "core-", "")
|
||||
shortName = strings.ReplaceAll(shortName, "agent-", "")
|
||||
nameItems := strings.Split(shortName, "-linux")
|
||||
if strings.HasSuffix(snap, ".tar.gz") {
|
||||
snap = strings.ReplaceAll(snap, ".tar.gz", "")
|
||||
}
|
||||
@@ -89,7 +89,7 @@ func (u *SnapshotService) SnapshotImport(req dto.SnapshotImport) error {
|
||||
Name: snap,
|
||||
SourceAccountIDs: fmt.Sprintf("%v", req.BackupAccountID),
|
||||
DownloadAccountID: req.BackupAccountID,
|
||||
Version: nameItems[1],
|
||||
Version: nameItems[0],
|
||||
Description: req.Description,
|
||||
Status: constant.StatusSuccess,
|
||||
}
|
||||
@@ -110,6 +110,7 @@ func (u *SnapshotService) LoadSnapshotData() (dto.SnapshotData, error) {
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
data.WithDockerConf = true
|
||||
data.PanelData, err = loadPanelFile(fileOp)
|
||||
if err != nil {
|
||||
return data, err
|
||||
@@ -403,3 +404,13 @@ func loadFile(pathItem string, index int, fileOp fileUtils.FileOp) ([]dto.DataTr
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func checkSnapshotIsOk(name string) bool {
|
||||
names := []string{"1panel-core-v2.", "1panel-agent-v2.", "1panel-v2.", "snapshot-1panel-core-v2.", "snapshot-1panel-agent-v2."}
|
||||
for _, item := range names {
|
||||
if strings.HasPrefix(name, item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -34,7 +35,7 @@ func (u *SnapshotService) SnapshotCreate(parentTask *task.Task, req dto.Snapshot
|
||||
scope = "agent"
|
||||
}
|
||||
if jobID == 0 {
|
||||
req.Name = fmt.Sprintf("1panel-%s-%s-linux-%s-%s", versionItem.Value, scope, loadOs(), time.Now().Format(constant.DateTimeSlimLayout))
|
||||
req.Name = fmt.Sprintf("1panel-%s-%s-linux-%s-%s", scope, versionItem.Value, loadOs(), time.Now().Format(constant.DateTimeSlimLayout))
|
||||
}
|
||||
appItem, _ := json.Marshal(req.AppData)
|
||||
panelItem, _ := json.Marshal(req.PanelData)
|
||||
@@ -50,11 +51,13 @@ func (u *SnapshotService) SnapshotCreate(parentTask *task.Task, req dto.Snapshot
|
||||
AppData: string(appItem),
|
||||
PanelData: string(panelItem),
|
||||
BackupData: string(backupItem),
|
||||
WithDockerConf: req.WithDockerConf,
|
||||
WithMonitorData: req.WithMonitorData,
|
||||
WithLoginLog: req.WithLoginLog,
|
||||
WithOperationLog: req.WithOperationLog,
|
||||
WithTaskLog: req.WithTaskLog,
|
||||
WithSystemLog: req.WithSystemLog,
|
||||
IgnoreFiles: strings.Join(req.IgnoreFiles, ","),
|
||||
|
||||
Version: versionItem.Value,
|
||||
Status: constant.StatusWaiting,
|
||||
@@ -106,13 +109,14 @@ func (u *SnapshotService) SnapshotReCreate(id uint) error {
|
||||
return err
|
||||
}
|
||||
req.TaskID = taskModel.ID
|
||||
taskItem, err := task.NewTaskWithOps(req.Name, task.TaskCreate, task.TaskScopeSnapshot, req.TaskID, req.ID)
|
||||
taskItem, err := task.ReNewTaskWithOps(req.Name, task.TaskCreate, task.TaskScopeSnapshot, req.TaskID, req.ID)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("new task for create snapshot failed, err: %v", err)
|
||||
return err
|
||||
}
|
||||
_ = snapshotRepo.Update(req.ID, map[string]interface{}{"status": constant.StatusWaiting, "message": ""})
|
||||
go func() {
|
||||
_ = handleSnapshot(req, taskItem, 0, 0, 0)
|
||||
_ = handleSnapshot(req, taskItem, 0, 3, 0)
|
||||
}()
|
||||
|
||||
return nil
|
||||
@@ -145,7 +149,7 @@ func handleSnapshot(req dto.SnapshotCreate, taskItem *task.Task, jobID, retry, t
|
||||
if len(req.InterruptStep) == 0 || req.InterruptStep == "SnapBaseInfo" {
|
||||
taskItem.AddSubTaskWithAliasAndOps(
|
||||
"SnapBaseInfo",
|
||||
func(t *task.Task) error { return snapBaseData(itemHelper, baseDir) },
|
||||
func(t *task.Task) error { return snapBaseData(itemHelper, baseDir, req.WithDockerConf) },
|
||||
nil, int(retry), time.Duration(timeout)*time.Second,
|
||||
)
|
||||
req.InterruptStep = ""
|
||||
@@ -233,6 +237,7 @@ func loadDbConn(snap *snapHelper, targetDir string, req dto.SnapshotCreate) erro
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = os.Remove(path.Join(targetDir, "db/session.db"))
|
||||
|
||||
agentDb, err := common.LoadDBConnByPathWithErr(path.Join(targetDir, "db/agent.db"), "agent.db")
|
||||
snap.Task.LogWithStatus(i18n.GetWithName("SnapNewDB", "agent"), err)
|
||||
@@ -284,7 +289,7 @@ func loadDbConn(snap *snapHelper, targetDir string, req dto.SnapshotCreate) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func snapBaseData(snap snapHelper, targetDir string) error {
|
||||
func snapBaseData(snap snapHelper, targetDir string, withDockerConf bool) error {
|
||||
snap.Task.Log("---------------------- 2 / 8 ----------------------")
|
||||
snap.Task.LogStart(i18n.GetMsgByKey("SnapBaseInfo"))
|
||||
|
||||
@@ -321,11 +326,13 @@ func snapBaseData(snap snapHelper, targetDir string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if snap.FileOp.Stat("/etc/docker/daemon.json") {
|
||||
err = snap.FileOp.CopyFile("/etc/docker/daemon.json", targetDir)
|
||||
snap.Task.LogWithStatus(i18n.GetWithName("SnapCopy", "/etc/docker/daemon.json"), err)
|
||||
if err != nil {
|
||||
return err
|
||||
if withDockerConf {
|
||||
if snap.FileOp.Stat(constant.DaemonJsonPath) {
|
||||
err = snap.FileOp.CopyFile(constant.DaemonJsonPath, targetDir)
|
||||
snap.Task.LogWithStatus(i18n.GetWithName("SnapCopy", constant.DaemonJsonPath), err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,8 +384,8 @@ func snapAppImage(snap snapHelper, req dto.SnapshotCreate, targetDir string) err
|
||||
}
|
||||
}
|
||||
|
||||
snap.Task.Log(strings.Join(imageList, " "))
|
||||
if len(imageList) != 0 {
|
||||
snap.Task.Log(strings.Join(imageList, " "))
|
||||
snap.Task.Logf("docker save %s | gzip -c > %s", strings.Join(imageList, " "), path.Join(targetDir, "images.tar.gz"))
|
||||
std, err := cmd.NewCommandMgr(cmd.WithTimeout(10*time.Minute)).RunWithStdoutBashCf("docker save %s | gzip -c > %s", strings.Join(imageList, " "), path.Join(targetDir, "images.tar.gz"))
|
||||
if err != nil {
|
||||
@@ -386,6 +393,8 @@ func snapAppImage(snap snapHelper, req dto.SnapshotCreate, targetDir string) err
|
||||
return errors.New(std)
|
||||
}
|
||||
snap.Task.LogSuccess(i18n.GetMsgByKey("SnapDockerSave"))
|
||||
} else {
|
||||
snap.Task.Log(i18n.GetMsgByKey("SnapInstallAppImageEmpty"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -395,6 +404,7 @@ func snapBackupData(snap snapHelper, req dto.SnapshotCreate, targetDir string) e
|
||||
snap.Task.LogStart(i18n.GetMsgByKey("SnapLocalBackup"))
|
||||
|
||||
excludes := loadBackupExcludes(snap, req.BackupData)
|
||||
excludes = append(excludes, req.IgnoreFiles...)
|
||||
excludes = append(excludes, "./system_snapshot")
|
||||
for _, item := range req.AppData {
|
||||
for _, itemApp := range item.Children {
|
||||
@@ -418,7 +428,8 @@ func loadBackupExcludes(snap snapHelper, req []dto.DataTree) []string {
|
||||
if err := snap.snapAgentDB.Where("file_dir = ? AND file_name = ?", strings.TrimPrefix(path.Dir(item.Path), global.Dir.LocalBackupDir+"/"), path.Base(item.Path)).Delete(&model.BackupRecord{}).Error; err != nil {
|
||||
snap.Task.LogWithStatus("delete backup file from database", err)
|
||||
}
|
||||
excludes = append(excludes, "."+strings.TrimPrefix(item.Path, global.Dir.LocalBackupDir))
|
||||
itemDir, _ := filepath.Rel(item.Path, global.Dir.LocalBackupDir)
|
||||
excludes = append(excludes, itemDir)
|
||||
} else {
|
||||
excludes = append(excludes, loadBackupExcludes(snap, item.Children)...)
|
||||
}
|
||||
@@ -430,7 +441,8 @@ func loadAppBackupExcludes(req []dto.DataTree) []string {
|
||||
for _, item := range req {
|
||||
if len(item.Children) == 0 {
|
||||
if !item.IsCheck {
|
||||
excludes = append(excludes, "."+strings.TrimPrefix(item.Path, path.Join(global.Dir.LocalBackupDir)))
|
||||
itemDir, _ := filepath.Rel(item.Path, global.Dir.LocalBackupDir)
|
||||
excludes = append(excludes, itemDir)
|
||||
}
|
||||
} else {
|
||||
excludes = append(excludes, loadAppBackupExcludes(item.Children)...)
|
||||
@@ -463,26 +475,21 @@ func snapPanelData(snap snapHelper, req dto.SnapshotCreate, targetDir string) er
|
||||
|
||||
rootDir := global.Dir.DataDir
|
||||
if strings.Contains(global.Dir.LocalBackupDir, rootDir) {
|
||||
excludes = append(excludes, "."+strings.ReplaceAll(global.Dir.LocalBackupDir, rootDir, ""))
|
||||
itemDir, _ := filepath.Rel(rootDir, global.Dir.LocalBackupDir)
|
||||
excludes = append(excludes, itemDir)
|
||||
}
|
||||
if len(snap.OpenrestyDir) != 0 && strings.Contains(snap.OpenrestyDir, rootDir) {
|
||||
excludes = append(excludes, "."+strings.ReplaceAll(snap.OpenrestyDir, rootDir, ""))
|
||||
}
|
||||
ignoreVal, _ := settingRepo.Get(settingRepo.WithByKey("SnapshotIgnore"))
|
||||
rules := strings.Split(ignoreVal.Value, ",")
|
||||
for _, ignore := range rules {
|
||||
if len(ignore) == 0 || cmd.CheckIllegal(ignore) {
|
||||
continue
|
||||
}
|
||||
excludes = append(excludes, "."+strings.ReplaceAll(ignore, rootDir, ""))
|
||||
itemDir, _ := filepath.Rel(rootDir, snap.OpenrestyDir)
|
||||
excludes = append(excludes, itemDir)
|
||||
}
|
||||
excludes = append(excludes, req.IgnoreFiles...)
|
||||
err := snap.FileOp.TarGzCompressPro(false, rootDir, path.Join(targetDir, "1panel_data.tar.gz"), "", strings.Join(excludes, ","))
|
||||
snap.Task.LogWithStatus(i18n.GetMsgByKey("SnapCompressPanel"), err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(snap.OpenrestyDir) != 0 {
|
||||
err := snap.FileOp.TarGzCompressPro(false, snap.OpenrestyDir, path.Join(targetDir, "website.tar.gz"), "", "")
|
||||
err := snap.FileOp.TarGzCompressPro(false, snap.OpenrestyDir, path.Join(targetDir, "website.tar.gz"), "", strings.Join(req.IgnoreFiles, ","))
|
||||
snap.Task.LogWithStatus(i18n.GetMsgByKey("SnapWebsite"), err)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -496,7 +503,8 @@ func loadPanelExcludes(req []dto.DataTree) []string {
|
||||
for _, item := range req {
|
||||
if len(item.Children) == 0 {
|
||||
if !item.IsCheck {
|
||||
excludes = append(excludes, "."+strings.TrimPrefix(item.Path, path.Join(global.Dir.BaseDir, "1panel")))
|
||||
itemDir, _ := filepath.Rel(item.Path, path.Join(global.Dir.BaseDir, "1panel"))
|
||||
excludes = append(excludes, itemDir)
|
||||
}
|
||||
} else {
|
||||
excludes = append(excludes, loadPanelExcludes(item.Children)...)
|
||||
|
||||
@@ -38,6 +38,18 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
|
||||
_ = snapshotRepo.Update(snap.ID, map[string]interface{}{"recover_status": constant.StatusFailed, "recover_message": errInfo})
|
||||
return errors.New(errInfo)
|
||||
}
|
||||
if !strings.Contains(snap.Name, "-v2.") {
|
||||
return errors.New("snapshots are currently not supported for recovery across major versions")
|
||||
}
|
||||
if !strings.Contains(snap.Name, "-core") && !strings.Contains(snap.Name, "-agent") {
|
||||
return errors.New("the name of the snapshot file does not conform to the format")
|
||||
}
|
||||
if strings.Contains(snap.Name, "-core") && !global.IsMaster {
|
||||
return errors.New("the snapshot of the master node cannot be restored on the agent nodes")
|
||||
}
|
||||
if strings.Contains(snap.Name, "-agent") && global.IsMaster {
|
||||
return errors.New("the snapshot of the agent node cannot be restored on the master node")
|
||||
}
|
||||
if len(snap.RollbackStatus) != 0 && snap.RollbackStatus != constant.StatusSuccess {
|
||||
req.IsNew = true
|
||||
}
|
||||
@@ -55,7 +67,13 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
|
||||
} else {
|
||||
_ = snapshotRepo.Update(snap.ID, map[string]interface{}{"task_recover_id": req.TaskID})
|
||||
}
|
||||
taskItem, err := task.NewTaskWithOps(snap.Name, task.TaskRecover, task.TaskScopeSnapshot, req.TaskID, snap.ID)
|
||||
|
||||
var taskItem *task.Task
|
||||
if req.IsNew {
|
||||
taskItem, err = task.NewTaskWithOps(snap.Name, task.TaskRecover, task.TaskScopeSnapshot, req.TaskID, snap.ID)
|
||||
} else {
|
||||
taskItem, err = task.ReNewTaskWithOps(snap.Name, task.TaskRecover, task.TaskScopeSnapshot, req.TaskID, snap.ID)
|
||||
}
|
||||
if err != nil {
|
||||
global.LOG.Errorf("new task for create snapshot failed, err: %v", err)
|
||||
return err
|
||||
@@ -84,7 +102,7 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
|
||||
taskItem.AddSubTaskWithAlias(
|
||||
"RecoverDecompress",
|
||||
func(t *task.Task) error {
|
||||
itemHelper.Task.Log("---------------------- 2 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 2 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetWithName("RecoverDecompress", snap.Name))
|
||||
err := itemHelper.FileOp.TarGzExtractPro(fmt.Sprintf("%s/%s.tar.gz", rootDir, snap.Name), rootDir, req.Secret)
|
||||
itemHelper.Task.LogWithStatus(i18n.GetMsgByKey("Decompress"), err)
|
||||
@@ -140,7 +158,7 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
|
||||
taskItem.AddSubTaskWithAlias(
|
||||
"RecoverBackups",
|
||||
func(t *task.Task) error {
|
||||
itemHelper.Task.Log("---------------------- 8 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 8 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetWithName("RecoverBackups", snap.Name))
|
||||
err := itemHelper.FileOp.TarGzExtractPro(path.Join(rootDir, snap.Name, "/1panel_backup.tar.gz"), snapJson.BackupDataDir, "")
|
||||
itemHelper.Task.LogWithStatus(i18n.GetMsgByKey("Decompress"), err)
|
||||
@@ -150,11 +168,29 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
|
||||
)
|
||||
req.IsNew = true
|
||||
}
|
||||
if req.IsNew || snap.InterruptStep == "RecoverWebsite" {
|
||||
taskItem.AddSubTaskWithAlias(
|
||||
"RecoverWebsite",
|
||||
func(t *task.Task) error {
|
||||
itemHelper.Task.Log("---------------------- 9 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetWithName("RecoverWebsite", snap.Name))
|
||||
webFile := path.Join(rootDir, snap.Name, "/website.tar.gz")
|
||||
var err error
|
||||
if itemHelper.FileOp.Stat(webFile) {
|
||||
err = itemHelper.FileOp.TarGzExtractPro(webFile, snapJson.OperestyDir, "")
|
||||
}
|
||||
itemHelper.Task.LogWithStatus(i18n.GetMsgByKey("Decompress"), err)
|
||||
return err
|
||||
},
|
||||
nil,
|
||||
)
|
||||
req.IsNew = true
|
||||
}
|
||||
if req.IsNew || snap.InterruptStep == "RecoverPanelData" {
|
||||
taskItem.AddSubTaskWithAlias(
|
||||
"RecoverPanelData",
|
||||
func(t *task.Task) error {
|
||||
itemHelper.Task.Log("---------------------- 9 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 10 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetWithName("RecoverPanelData", snap.Name))
|
||||
err := itemHelper.FileOp.TarGzExtractPro(path.Join(rootDir, snap.Name, "/1panel_data.tar.gz"), path.Join(snapJson.BaseDir, "1panel"), "")
|
||||
itemHelper.Task.LogWithStatus(i18n.GetMsgByKey("Decompress"), err)
|
||||
@@ -195,7 +231,7 @@ func (u *SnapshotService) SnapshotRecover(req dto.SnapshotRecover) error {
|
||||
}
|
||||
|
||||
func handleDownloadSnapshot(itemHelper *snapRecoverHelper, snap model.Snapshot, targetDir string) error {
|
||||
itemHelper.Task.Log("---------------------- 1 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 1 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetMsgByKey("RecoverDownload"))
|
||||
|
||||
account, client, err := NewBackupClientWithID(snap.DownloadAccountID)
|
||||
@@ -214,7 +250,7 @@ func handleDownloadSnapshot(itemHelper *snapRecoverHelper, snap model.Snapshot,
|
||||
}
|
||||
|
||||
func backupBeforeRecover(name string, itemHelper *snapRecoverHelper) error {
|
||||
itemHelper.Task.Log("---------------------- 3 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 3 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetMsgByKey("BackupBeforeRecover"))
|
||||
|
||||
rootDir := fmt.Sprintf("%s/1panel_original/original_%s", global.Dir.BaseDir, name)
|
||||
@@ -273,9 +309,9 @@ func backupBeforeRecover(name string, itemHelper *snapRecoverHelper) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if itemHelper.FileOp.Stat("/etc/docker/daemon.json") {
|
||||
err = itemHelper.FileOp.CopyFile("/etc/docker/daemon.json", baseDir)
|
||||
itemHelper.Task.LogWithStatus(i18n.GetWithName("SnapCopy", "/etc/docker/daemon.json"), err)
|
||||
if itemHelper.FileOp.Stat(constant.DaemonJsonPath) {
|
||||
err = itemHelper.FileOp.CopyFile(constant.DaemonJsonPath, baseDir)
|
||||
itemHelper.Task.LogWithStatus(i18n.GetWithName("SnapCopy", constant.DaemonJsonPath), err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -284,7 +320,7 @@ func backupBeforeRecover(name string, itemHelper *snapRecoverHelper) error {
|
||||
}
|
||||
|
||||
func readFromJson(rootDir string, itemHelper *snapRecoverHelper) (SnapshotJson, error) {
|
||||
itemHelper.Task.Log("---------------------- 4 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 4 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetMsgByKey("Readjson"))
|
||||
|
||||
snapJsonPath := path.Join(rootDir, "base/snapshot.json")
|
||||
@@ -308,7 +344,7 @@ func readFromJson(rootDir string, itemHelper *snapRecoverHelper) (SnapshotJson,
|
||||
}
|
||||
|
||||
func recoverAppData(src string, itemHelper *snapRecoverHelper) error {
|
||||
itemHelper.Task.Log("---------------------- 5 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 5 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetMsgByKey("RecoverApp"))
|
||||
|
||||
if _, err := os.Stat(path.Join(src, "images.tar.gz")); err != nil {
|
||||
@@ -325,7 +361,7 @@ func recoverAppData(src string, itemHelper *snapRecoverHelper) error {
|
||||
}
|
||||
|
||||
func recoverBaseData(src string, itemHelper *snapRecoverHelper) error {
|
||||
itemHelper.Task.Log("---------------------- 6 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 6 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetMsgByKey("SnapBaseInfo"))
|
||||
|
||||
if global.IsMaster {
|
||||
@@ -356,15 +392,11 @@ func recoverBaseData(src string, itemHelper *snapRecoverHelper) error {
|
||||
return err
|
||||
}
|
||||
|
||||
daemonJsonPath := "/etc/docker/daemon.json"
|
||||
_, errSrc := os.Stat(path.Join(src, "docker/daemon.json"))
|
||||
_, errPath := os.Stat(daemonJsonPath)
|
||||
if os.IsNotExist(errSrc) && os.IsNotExist(errPath) {
|
||||
if !itemHelper.FileOp.Stat(path.Join(src, "daemon.json")) {
|
||||
itemHelper.Task.Log(i18n.GetMsgByKey("RecoverDaemonJsonEmpty"))
|
||||
return nil
|
||||
}
|
||||
if errSrc == nil {
|
||||
err = itemHelper.FileOp.CopyFile(path.Join(src, "docker/daemon.json"), "/etc/docker")
|
||||
} else {
|
||||
err = itemHelper.FileOp.CopyFile(path.Join(src, "daemon.json"), path.Dir(constant.DaemonJsonPath))
|
||||
itemHelper.Task.Log(i18n.GetMsgByKey("RecoverDaemonJson"))
|
||||
if err != nil {
|
||||
return fmt.Errorf("recover docker daemon.json failed, err: %v", err)
|
||||
@@ -378,7 +410,7 @@ func recoverBaseData(src string, itemHelper *snapRecoverHelper) error {
|
||||
}
|
||||
|
||||
func recoverDBData(src string, itemHelper *snapRecoverHelper) error {
|
||||
itemHelper.Task.Log("---------------------- 7 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 7 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetMsgByKey("RecoverDBData"))
|
||||
err := itemHelper.FileOp.CopyDirWithExclude(src, global.Dir.DataDir, nil)
|
||||
|
||||
@@ -387,7 +419,7 @@ func recoverDBData(src string, itemHelper *snapRecoverHelper) error {
|
||||
}
|
||||
|
||||
func restartCompose(composePath string, itemHelper *snapRecoverHelper) error {
|
||||
itemHelper.Task.Log("---------------------- 10 / 10 ----------------------")
|
||||
itemHelper.Task.Log("---------------------- 11 / 11 ----------------------")
|
||||
itemHelper.Task.LogStart(i18n.GetMsgByKey("RecoverCompose"))
|
||||
|
||||
composes, err := composeRepo.ListRecord()
|
||||
|
||||
@@ -76,9 +76,12 @@ func (u *SnapshotService) SnapshotRollback(req dto.SnapshotRecover) error {
|
||||
nil,
|
||||
)
|
||||
taskItem.AddSubTask(
|
||||
i18n.GetWithName("SnapCopy", "/etc/docker/daemon.json"),
|
||||
i18n.GetWithName("SnapCopy", constant.DaemonJsonPath),
|
||||
func(t *task.Task) error {
|
||||
return FileOp.CopyFile(path.Join(baseDir, "daemon.json"), "/etc/docker")
|
||||
if FileOp.Stat(path.Join(baseDir, "daemon.json")) {
|
||||
return FileOp.CopyFile(path.Join(baseDir, "daemon.json"), path.Dir(constant.DaemonJsonPath))
|
||||
}
|
||||
return nil
|
||||
},
|
||||
nil,
|
||||
)
|
||||
|
||||
@@ -415,6 +415,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
|
||||
return err
|
||||
}
|
||||
website.ParentWebsiteID = parentWebsite.ID
|
||||
website.SiteDir = create.SiteDir
|
||||
}
|
||||
|
||||
configNginx := func(t *task.Task) error {
|
||||
@@ -922,18 +923,12 @@ func (w WebsiteService) GetWebsiteHTTPS(websiteId uint) (response.WebsiteHTTPS,
|
||||
res response.WebsiteHTTPS
|
||||
httpsPorts []string
|
||||
)
|
||||
websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(websiteId))
|
||||
for _, domain := range websiteDomains {
|
||||
if domain.SSL {
|
||||
httpsPorts = append(httpsPorts, strconv.Itoa(domain.Port))
|
||||
}
|
||||
}
|
||||
if len(httpsPorts) == 0 {
|
||||
nginxInstall, _ := getAppInstallByKey(constant.AppOpenresty)
|
||||
res.HttpsPort = strconv.Itoa(nginxInstall.HttpsPort)
|
||||
} else {
|
||||
res.HttpsPort = strings.Join(httpsPorts, ",")
|
||||
|
||||
httpsPortsMap := getHttpsPort(websiteId)
|
||||
for port := range httpsPortsMap {
|
||||
httpsPorts = append(httpsPorts, strconv.Itoa(port))
|
||||
}
|
||||
res.HttpsPort = strings.Join(httpsPorts, ",")
|
||||
if website.WebsiteSSLID == 0 {
|
||||
res.Enable = false
|
||||
return res, nil
|
||||
@@ -981,10 +976,6 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
||||
res response.WebsiteHTTPS
|
||||
websiteSSL model.WebsiteSSL
|
||||
)
|
||||
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = ChangeHSTSConfig(req.Hsts, req.Http3, website); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -995,24 +986,27 @@ func (w WebsiteService) OpWebsiteHTTPS(ctx context.Context, req request.WebsiteH
|
||||
website.Protocol = constant.ProtocolHTTP
|
||||
website.WebsiteSSLID = 0
|
||||
|
||||
httpsPorts, err := getHttpsPort(&website)
|
||||
websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(website.ID))
|
||||
|
||||
ports := make(map[int]struct{})
|
||||
for _, domain := range websiteDomains {
|
||||
ports[domain.Port] = struct{}{}
|
||||
}
|
||||
for port := range ports {
|
||||
if err = removeSSLListen(website, []string{strconv.Itoa(port)}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(httpsPorts) == 1 && httpsPorts[0] == nginxInstall.HttpsPort {
|
||||
httpsPortStr := strconv.Itoa(httpsPorts[0])
|
||||
if _, ok := ports[nginxInstall.HttpsPort]; !ok {
|
||||
httpsPortStr := strconv.Itoa(nginxInstall.HttpsPort)
|
||||
if err = deleteListenAndServerName(website, []string{httpsPortStr, "[::]:" + httpsPortStr}, []string{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
for _, port := range httpsPorts {
|
||||
httpsPortStr := strconv.Itoa(port)
|
||||
if err = removeSSLListen(website, []string{httpsPortStr}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nginxParams := getNginxParamsFromStaticFile(dto.SSL, nil)
|
||||
nginxParams = append(nginxParams,
|
||||
dto.NginxParam{
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -182,8 +183,8 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a
|
||||
return err
|
||||
}
|
||||
configPath := GetSitePath(*website, SiteConf)
|
||||
nginxContent := string(nginx_conf.WebsiteDefault)
|
||||
config, err := parser.NewStringParser(nginxContent).Parse()
|
||||
nginxContent := nginx_conf.GetWebsiteFile("website_default.conf")
|
||||
config, err := parser.NewStringParser(string(nginxContent)).Parse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -651,22 +652,33 @@ func createPemFile(website model.Website, websiteSSL model.WebsiteSSL) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getHttpsPort(website *model.Website) ([]int, error) {
|
||||
websiteDomains, _ := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(website.ID))
|
||||
var httpsPorts []int
|
||||
for _, domain := range websiteDomains {
|
||||
if domain.SSL {
|
||||
httpsPorts = append(httpsPorts, domain.Port)
|
||||
func getHttpsPort(websiteID uint) map[int]struct{} {
|
||||
domains, err := websiteDomainRepo.GetBy(websiteDomainRepo.WithWebsiteId(websiteID))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
httpsPorts := make(map[int]struct{})
|
||||
nginxInstall, _ := getAppInstallByKey(constant.AppOpenresty)
|
||||
hasDefaultPort := false
|
||||
for _, domain := range domains {
|
||||
if domain.Port == nginxInstall.HttpPort {
|
||||
hasDefaultPort = true
|
||||
}
|
||||
if domain.SSL {
|
||||
httpsPorts[domain.Port] = struct{}{}
|
||||
}
|
||||
}
|
||||
if hasDefaultPort {
|
||||
httpsPorts[nginxInstall.HttpsPort] = struct{}{}
|
||||
}
|
||||
if len(httpsPorts) == 0 {
|
||||
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for _, domain := range domains {
|
||||
if !domain.SSL {
|
||||
httpsPorts[domain.Port] = struct{}{}
|
||||
}
|
||||
}
|
||||
httpsPorts = append(httpsPorts, nginxInstall.HttpsPort)
|
||||
}
|
||||
return httpsPorts, nil
|
||||
return httpsPorts
|
||||
}
|
||||
|
||||
func applySSL(website *model.Website, websiteSSL model.WebsiteSSL, req request.WebsiteHTTPSOp) error {
|
||||
@@ -678,63 +690,71 @@ func applySSL(website *model.Website, websiteSSL model.WebsiteSSL, req request.W
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
noDefaultPort := true
|
||||
httpPorts := make(map[int]struct{})
|
||||
httpsPorts := make(map[int]struct{})
|
||||
|
||||
hasDefaultPort := false
|
||||
for _, domain := range domains {
|
||||
if domain.Port == 80 {
|
||||
noDefaultPort = false
|
||||
if domain.Port == nginxFull.Install.HttpPort {
|
||||
hasDefaultPort = true
|
||||
}
|
||||
if domain.Port != 80 && !domain.SSL {
|
||||
if domain.SSL {
|
||||
httpsPorts[domain.Port] = struct{}{}
|
||||
} else {
|
||||
httpPorts[domain.Port] = struct{}{}
|
||||
}
|
||||
}
|
||||
if hasDefaultPort {
|
||||
httpsPorts[nginxFull.Install.HttpsPort] = struct{}{}
|
||||
}
|
||||
if len(httpsPorts) == 0 {
|
||||
for port := range httpPorts {
|
||||
httpsPorts[port] = struct{}{}
|
||||
}
|
||||
}
|
||||
config := nginxFull.SiteConfig.Config
|
||||
server := config.FindServers()[0]
|
||||
|
||||
httpPort := strconv.Itoa(nginxFull.Install.HttpPort)
|
||||
httpsPort, err := getHttpsPort(website)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
httpPortIPV6 := "[::]:" + httpPort
|
||||
defaultHttpPort := strconv.Itoa(nginxFull.Install.HttpPort)
|
||||
defaultHttpPortIPV6 := "[::]:" + defaultHttpPort
|
||||
|
||||
for _, port := range httpsPort {
|
||||
if _, ok := httpPorts[port]; !ok {
|
||||
server.DeleteListen(strconv.Itoa(port))
|
||||
}
|
||||
setListen(server, strconv.Itoa(port), website.IPV6, req.Http3, website.DefaultServer, true)
|
||||
for port := range httpsPorts {
|
||||
portStr := strconv.Itoa(port)
|
||||
server.RemoveListenByBind(portStr)
|
||||
server.RemoveListenByBind("[::]:" + portStr)
|
||||
setListen(server, portStr, website.IPV6, req.Http3, website.DefaultServer, true)
|
||||
}
|
||||
|
||||
server.UpdateDirective("http2", []string{"on"})
|
||||
|
||||
switch req.HttpConfig {
|
||||
case constant.HTTPSOnly:
|
||||
server.RemoveListenByBind(httpPort)
|
||||
server.RemoveListenByBind(httpPortIPV6)
|
||||
server.RemoveListenByBind(defaultHttpPort)
|
||||
server.RemoveListenByBind(defaultHttpPortIPV6)
|
||||
server.RemoveDirective("if", []string{"($scheme"})
|
||||
case constant.HTTPToHTTPS:
|
||||
if !noDefaultPort {
|
||||
server.UpdateListen(httpPort, website.DefaultServer)
|
||||
}
|
||||
if website.IPV6 {
|
||||
server.UpdateListen(httpPortIPV6, website.DefaultServer)
|
||||
if hasDefaultPort {
|
||||
server.UpdateListen(defaultHttpPort, website.DefaultServer)
|
||||
if website.IPV6 {
|
||||
server.UpdateListen(defaultHttpPortIPV6, website.DefaultServer)
|
||||
}
|
||||
}
|
||||
server.AddHTTP2HTTPS()
|
||||
case constant.HTTPAlso:
|
||||
if !noDefaultPort {
|
||||
server.UpdateListen(httpPort, website.DefaultServer)
|
||||
if hasDefaultPort {
|
||||
server.UpdateListen(defaultHttpPort, website.DefaultServer)
|
||||
if website.IPV6 {
|
||||
server.UpdateListen(defaultHttpPortIPV6, website.DefaultServer)
|
||||
}
|
||||
}
|
||||
server.RemoveDirective("if", []string{"($scheme"})
|
||||
if website.IPV6 {
|
||||
server.UpdateListen(httpPortIPV6, website.DefaultServer)
|
||||
}
|
||||
}
|
||||
|
||||
if !req.Hsts {
|
||||
server.RemoveDirective("add_header", []string{"Strict-Transport-Security", "\"max-age=31536000\""})
|
||||
}
|
||||
if !req.Http3 {
|
||||
for _, port := range httpsPort {
|
||||
for port := range httpsPorts {
|
||||
server.RemoveListen(strconv.Itoa(port), "quic")
|
||||
if website.IPV6 {
|
||||
httpsPortIPV6 := "[::]:" + strconv.Itoa(port)
|
||||
@@ -1078,7 +1098,7 @@ func getWebsiteDomains(domains []request.WebsiteDomain, defaultPort int, website
|
||||
err = buserr.WithMap("ErrPortExist", errMap, nil)
|
||||
return
|
||||
}
|
||||
if common.ScanPort(port) {
|
||||
if port != 443 && common.ScanPort(port) {
|
||||
err = buserr.WithDetail("ErrPortInUsed", port, nil)
|
||||
return
|
||||
}
|
||||
@@ -1117,7 +1137,6 @@ func saveCertificateFile(websiteSSL *model.WebsiteSSL, logger *log.Logger) {
|
||||
func GetSystemSSL() (bool, uint) {
|
||||
sslSetting, err := settingRepo.Get(settingRepo.WithByKey("SSL"))
|
||||
if err != nil {
|
||||
global.LOG.Errorf("load service ssl from setting failed, err: %v", err)
|
||||
return false, 0
|
||||
}
|
||||
if sslSetting.Value == "enable" {
|
||||
@@ -1425,3 +1444,22 @@ func hasDefaultServer(params []string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ParseDomain(domain string) (*model.WebsiteDomain, error) {
|
||||
host, portStr, err := net.SplitHostPort(domain)
|
||||
if err != nil {
|
||||
return &model.WebsiteDomain{
|
||||
Domain: domain,
|
||||
Port: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid port in domain %s: %v", domain, err)
|
||||
}
|
||||
return &model.WebsiteDomain{
|
||||
Domain: host,
|
||||
Port: port,
|
||||
}, nil
|
||||
}
|
||||
|
||||
+35
-1
@@ -142,6 +142,40 @@ func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, e
|
||||
return task, nil
|
||||
}
|
||||
|
||||
func ReNewTaskWithOps(resourceName, operate, scope, taskID string, resourceID uint) (*Task, error) {
|
||||
return ReNewTask(GetTaskName(resourceName, operate, scope), operate, scope, taskID, resourceID)
|
||||
}
|
||||
func ReNewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, error) {
|
||||
if taskID == "" {
|
||||
return NewTask(name, operate, taskScope, taskID, resourceID)
|
||||
}
|
||||
logDir := path.Join(global.Dir.TaskDir, taskScope)
|
||||
if _, err := os.Stat(logDir); err != nil {
|
||||
if err = os.MkdirAll(logDir, constant.DirPerm); err != nil {
|
||||
return nil, fmt.Errorf("failed to create log directory: %w", err)
|
||||
}
|
||||
}
|
||||
logPath := path.Join(global.Dir.TaskDir, taskScope, taskID+".log")
|
||||
file, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, constant.FilePerm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open log file: %w", err)
|
||||
}
|
||||
writer := bufio.NewWriter(file)
|
||||
logger := log.New(file, "", log.LstdFlags)
|
||||
taskModel := &model.Task{
|
||||
ID: taskID,
|
||||
Name: name,
|
||||
Type: taskScope,
|
||||
LogFile: logPath,
|
||||
Status: constant.StatusExecuting,
|
||||
ResourceID: resourceID,
|
||||
Operate: operate,
|
||||
}
|
||||
taskRepo := repo.NewITaskRepo()
|
||||
task := &Task{Name: name, logFile: file, Logger: logger, taskRepo: taskRepo, Task: taskModel, Writer: writer}
|
||||
return task, nil
|
||||
}
|
||||
|
||||
func (t *Task) AddSubTask(name string, action ActionFunc, rollback RollbackFunc) {
|
||||
subTask := &SubTask{RootTask: t, Name: name, Retry: 0, Timeout: 30 * time.Minute, Action: action, Rollback: rollback}
|
||||
t.SubTasks = append(t.SubTasks, subTask)
|
||||
@@ -158,7 +192,7 @@ func (t *Task) AddSubTaskWithOps(name string, action ActionFunc, rollback Rollba
|
||||
}
|
||||
|
||||
func (t *Task) AddSubTaskWithAliasAndOps(key string, action ActionFunc, rollback RollbackFunc, retry int, timeout time.Duration) {
|
||||
subTask := &SubTask{RootTask: t, Name: i18n.GetMsgByKey(key), Retry: retry, Timeout: timeout, Action: action, Rollback: rollback}
|
||||
subTask := &SubTask{RootTask: t, Name: i18n.GetMsgByKey(key), StepAlias: key, Retry: retry, Timeout: timeout, Action: action, Rollback: rollback}
|
||||
t.SubTasks = append(t.SubTasks, subTask)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,6 @@ import (
|
||||
//go:embed ssl.conf
|
||||
var SSL []byte
|
||||
|
||||
//go:embed website_default.conf
|
||||
var WebsiteDefault []byte
|
||||
|
||||
//go:embed index.html
|
||||
var Index []byte
|
||||
|
||||
@@ -48,7 +45,7 @@ var Upstream []byte
|
||||
//go:embed sse.conf
|
||||
var SSE []byte
|
||||
|
||||
//go:embed *.json
|
||||
//go:embed *.json *.conf
|
||||
var websitesFiles embed.FS
|
||||
|
||||
func GetWebsiteFile(filename string) []byte {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
[global]
|
||||
error_log = /var/log/php/fpm.error.log
|
||||
log_level = notice
|
||||
[www]
|
||||
user = www-data
|
||||
group = www-data
|
||||
listen = 0.0.0.0:9000
|
||||
pm = dynamic
|
||||
pm.max_children = 10
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 1
|
||||
pm.max_spare_servers = 3
|
||||
pm.status_path = /status
|
||||
slowlog = /var/log/php/fpm.slow.log
|
||||
request_slowlog_timeout = 3
|
||||
catch_workers_output = yes
|
||||
@@ -15,9 +15,16 @@ server {
|
||||
|
||||
access_log /www/sites/domain/log/access.log main;
|
||||
error_log /www/sites/domain/log/error.log;
|
||||
|
||||
|
||||
location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md){
|
||||
return 404;
|
||||
}
|
||||
location ^~ /.well-known{
|
||||
allow all;
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {
|
||||
return 403;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,6 @@ const (
|
||||
ComposeOpStop = "stop"
|
||||
ComposeOpRestart = "restart"
|
||||
ComposeOpRemove = "remove"
|
||||
|
||||
DaemonJsonPath = "/etc/docker/daemon.json"
|
||||
)
|
||||
|
||||
var DaemonJsonPath = "/etc/docker/daemon.json"
|
||||
|
||||
@@ -41,11 +41,11 @@ var RuntimeDefaultVolumes = map[string]string{
|
||||
|
||||
var PHPDefaultVolumes = map[string]string{
|
||||
"${PANEL_WEBSITE_DIR}": "/www/",
|
||||
"./conf": "/usr/local/etc/php",
|
||||
"./conf/php.ini": "/usr/local/etc/php/php.ini",
|
||||
"./conf/conf.d": "/usr/local/etc/php/conf.d",
|
||||
"./conf/php-fpm.conf": "/usr/local/etc/php-fpm.d/www.conf",
|
||||
"./conf/php-fpm.conf": "/usr/local/etc/php-fpm.conf",
|
||||
"./log": "/var/log/php",
|
||||
"./extensions": "${EXTENSION_DIR}",
|
||||
"./extensions": "/usr/local/lib/php/extensions",
|
||||
"./supervisor/supervisord.conf": "/etc/supervisord.conf",
|
||||
"./supervisor/supervisor.d/php-fpm.ini": "/etc/supervisor.d/php-fpm.ini",
|
||||
"./supervisor/supervisor.d": "/etc/supervisor.d",
|
||||
|
||||
@@ -18,7 +18,7 @@ func NewBackupJob() *backup {
|
||||
|
||||
func (b *backup) Run() {
|
||||
var backups []model.BackupAccount
|
||||
_ = global.DB.Where("`type` in (?) AND is_public = 0", []string{constant.OneDrive, constant.ALIYUN, constant.GoogleDrive}).Find(&backups)
|
||||
_ = global.DB.Where("`type` in (?) AND is_public = 0", []string{constant.OneDrive, constant.ALIYUN}).Find(&backups)
|
||||
if len(backups) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -39,8 +39,6 @@ func (b *backup) Run() {
|
||||
switch backupItem.Type {
|
||||
case constant.OneDrive:
|
||||
refreshToken, err = client.RefreshToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.GoogleDrive:
|
||||
refreshToken, err = client.RefreshGoogleToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.ALIYUN:
|
||||
refreshToken, err = client.RefreshALIToken(varMap)
|
||||
}
|
||||
|
||||
+11
-11
@@ -40,6 +40,7 @@ require (
|
||||
github.com/shirou/gopsutil/v3 v3.24.5
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/afero v1.11.0
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/viper v1.19.0
|
||||
github.com/studio-b12/gowebdav v0.9.0
|
||||
github.com/subosito/gotenv v1.6.0
|
||||
@@ -53,7 +54,7 @@ require (
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/gorm v1.25.11
|
||||
gorm.io/gorm v1.30.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -98,7 +99,7 @@ require (
|
||||
github.com/fvbommel/sortorder v1.1.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||
github.com/glebarez/go-sqlite v1.22.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
@@ -106,7 +107,7 @@ require (
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.3.0 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
@@ -114,7 +115,6 @@ require (
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
|
||||
github.com/h2non/filetype v1.1.1 // indirect
|
||||
@@ -162,6 +162,7 @@ require (
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/mozillazg/go-httpheader v0.2.1 // indirect
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/nrdcg/dnspod-go v0.4.0 // indirect
|
||||
github.com/nrdcg/freemyip v0.3.0 // indirect
|
||||
github.com/nrdcg/mailinabox v0.2.0 // indirect
|
||||
@@ -184,7 +185,6 @@ require (
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/cobra v1.9.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1128 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1128 // indirect
|
||||
@@ -224,17 +224,17 @@ require (
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/sync v0.15.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.33.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
||||
google.golang.org/grpc v1.72.2 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
modernc.org/libc v1.22.5 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/sqlite v1.23.1 // indirect
|
||||
modernc.org/libc v1.66.1 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
modernc.org/sqlite v1.38.0 // indirect
|
||||
)
|
||||
|
||||
+41
-23
@@ -257,8 +257,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
|
||||
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
|
||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/go-acme/lego/v4 v4.23.1 h1:lZ5fGtGESA2L9FB8dNTvrQUq3/X4QOb8ExkKyY7LSV4=
|
||||
@@ -311,8 +311,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk=
|
||||
github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw=
|
||||
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
@@ -396,8 +396,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM=
|
||||
github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
@@ -571,9 +571,8 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
|
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrSSDunscGsRM=
|
||||
github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A=
|
||||
@@ -650,6 +649,8 @@ github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/
|
||||
github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
|
||||
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
@@ -755,7 +756,6 @@ github.com/qiniu/go-sdk/v7 v7.21.1/go.mod h1:8EM2awITynlem2VML2dXGHkMYP2UyECsGLO
|
||||
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
@@ -1004,8 +1004,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
@@ -1261,8 +1261,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
||||
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -1396,8 +1396,8 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
|
||||
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
||||
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
|
||||
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -1407,14 +1407,32 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
|
||||
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
|
||||
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||
modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
|
||||
modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
|
||||
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
|
||||
modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA=
|
||||
modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/goabi0 v0.0.3 h1:y81b9r3asCh6Xtse6Nz85aYGB0cG3M3U6222yap1KWI=
|
||||
modernc.org/goabi0 v0.0.3/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||
modernc.org/libc v1.66.1 h1:4uQsntXbVyAgrV+j6NhKvDiUypoJL48BWQx6sy9y8ok=
|
||||
modernc.org/libc v1.66.1/go.mod h1:AiZxInURfEJx516LqEaFcrC+X38rt9G7+8ojIXQKHbo=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI=
|
||||
modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
||||
@@ -205,6 +205,8 @@ SystemLog: 'System Log'
|
||||
CutWebsiteLog: 'Rotate Website Log'
|
||||
FileOrDir: 'Directory / File'
|
||||
UploadFile: 'Uploading backup file {{ .file }} to {{ .backup }}'
|
||||
IgnoreBackupErr: 'Backup failed, error: {{ .detail }}, ignoring this error...'
|
||||
IgnoreUploadErr: 'Upload failed, error: {{ .detail }}, ignoring this error...'
|
||||
|
||||
#toolbox
|
||||
ErrNotExistUser: 'The current user does not exist, please modify and try again!'
|
||||
@@ -333,6 +335,7 @@ SnapDeleteLoginLog: 'Delete access log'
|
||||
SnapDeleteMonitor: 'Delete monitoring data'
|
||||
SnapRemoveSystemIP: 'Remove system IP'
|
||||
SnapBaseInfo: 'Write 1Panel basic information'
|
||||
SnapInstallAppImageEmpty: 'No application images selected, skipping...'
|
||||
SnapInstallApp: 'Backup 1Panel installed applications'
|
||||
SnapDockerSave: 'Compress installed applications'
|
||||
SnapLocalBackup: 'Backup 1Panel local backup directory'
|
||||
|
||||
@@ -205,6 +205,8 @@ SystemLog: 'システムログ'
|
||||
CutWebsiteLog: 'ウェブサイトログのローテーション'
|
||||
FileOrDir: 'ディレクトリ / ファイル'
|
||||
UploadFile: 'バックアップファイル {{ .file }} を {{ .backup }} にアップロード中'
|
||||
IgnoreBackupErr: 'バックアップ失敗、エラー:{{ .detail }}、このエラーを無視します...'
|
||||
IgnoreUploadErr: 'アップロード失敗、エラー:{{ .detail }}、このエラーを無視します...'
|
||||
|
||||
#toolbox
|
||||
ErrNotExistUser: '現在のユーザーは存在しません。変更してもう一度お試しください。'
|
||||
@@ -333,7 +335,8 @@ SnapDeleteLoginLog: 'アクセスログを削除する'
|
||||
SnapDeleteMonitor: '監視データを削除する'
|
||||
SnapRemoveSystemIP: 'システム IP を削除します'
|
||||
SnapBaseInfo: '1Panel の基本情報を書き込む'
|
||||
SnapInstallApp: '1Panel にインストールされたアプリケーションをバックアップする'
|
||||
SnapInstallAppImageEmpty: 'アプリケーションイメージが選択されていないため、スキップします...'
|
||||
SnapInstallApp: '1Panelインストール済みアプリケーションのバックアップ'
|
||||
SnapDockerSave: 'インストールされたアプリケーションを圧縮する'
|
||||
SnapLocalBackup: '1Panel ローカル バックアップ ディレクトリをバックアップします'
|
||||
SnapCompressBackup: 'ローカル バックアップ ディレクトリを圧縮する'
|
||||
|
||||
@@ -205,6 +205,8 @@ SystemLog: '시스템 로그'
|
||||
CutWebsiteLog: '웹사이트 로그 회전'
|
||||
FileOrDir: '디렉터리 / 파일'
|
||||
UploadFile: '백업 파일 {{ .file }} 을(를) {{ .backup }}(으)로 업로드 중'
|
||||
IgnoreBackupErr: 'Sandaran gagal, ralat: {{ .detail }}, abaikan ralat ini...'
|
||||
IgnoreUploadErr: 'Muat naik gagal, ralat: {{ .detail }}, abaikan ralat ini...'
|
||||
|
||||
#도구상자
|
||||
ErrNotExistUser: '현재 사용자가 존재하지 않습니다. 수정한 후 다시 시도하세요!'
|
||||
@@ -333,6 +335,7 @@ SnapDeleteLoginLog: '액세스 로그 삭제'
|
||||
SnapDeleteMonitor: '모니터링 데이터 삭제'
|
||||
SnapRemoveSystemIP: '시스템 IP 제거'
|
||||
SnapBaseInfo: '1패널 기본 정보 쓰기'
|
||||
SnapInstallAppImageEmpty: '애플리케이션 이미지가 선택되지 않아 건너뜁니다...'
|
||||
SnapInstallApp: '1Panel 설치된 애플리케이션 백업'
|
||||
SnapDockerSave: '설치된 애플리케이션 압축'
|
||||
SnapLocalBackup: '1Panel 로컬 백업 디렉토리 백업'
|
||||
|
||||
@@ -204,6 +204,8 @@ SystemLog: 'Log Sistem'
|
||||
CutWebsiteLog: 'Putar Log Laman Web'
|
||||
FileOrDir: 'Direktori / Fail'
|
||||
UploadFile: 'Muat naik fail sandaran {{ .file }} ke {{ .backup }}'
|
||||
IgnoreBackupErr: 'Sandaran gagal, ralat: {{ .detail }}, abaikan ralat ini...'
|
||||
IgnoreUploadErr: 'Muat naik gagal, ralat: {{ .detail }}, abaikan ralat ini...'
|
||||
|
||||
#kotak alat
|
||||
ErrNotExistUser: 'Pengguna semasa tidak wujud, sila ubah suai dan cuba lagi!'
|
||||
@@ -332,7 +334,8 @@ SnapDeleteLoginLog: 'Padam log akses'
|
||||
SnapDeleteMonitor: 'Padamkan data pemantauan'
|
||||
SnapRemoveSystemIP: 'Alih keluar IP sistem'
|
||||
SnapBaseInfo: 'Tulis maklumat asas 1Panel'
|
||||
SnapInstallApp: 'Aplikasi yang dipasang sandaran 1Panel'
|
||||
SnapInstallAppImageEmpty: 'Tiada imej aplikasi dipilih, dilangkau...'
|
||||
SnapInstallApp: 'Sandaran aplikasi terpasang 1Panel'
|
||||
SnapDockerSave: 'Mampatkan aplikasi yang dipasang'
|
||||
SnapLocalBackup: 'Sandaran 1Panel direktori sandaran tempatan'
|
||||
SnapCompressBackup: 'Mampatkan direktori sandaran tempatan'
|
||||
|
||||
@@ -205,6 +205,8 @@ SystemLog: 'Log do Sistema'
|
||||
CutWebsiteLog: 'Rotacionar Log do Website'
|
||||
FileOrDir: 'Diretório / Arquivo'
|
||||
UploadFile: 'Enviando arquivo de backup {{ .file }} para {{ .backup }}'
|
||||
IgnoreBackupErr: 'Backup falhou, erro: {{ .detail }}, ignorando este erro...'
|
||||
IgnoreUploadErr: 'Upload falhou, erro: {{ .detail }}, ignorando este erro...'
|
||||
|
||||
#caixa de ferramentas
|
||||
ErrNotExistUser: 'O usuário atual não existe, modifique e tente novamente!'
|
||||
@@ -333,7 +335,8 @@ SnapDeleteLoginLog: 'Excluir log de acesso'
|
||||
SnapDeleteMonitor: 'Excluir dados de monitoramento'
|
||||
SnapRemoveSystemIP: 'Remover IP do sistema'
|
||||
SnapBaseInfo: 'Escreva informações básicas do 1Panel'
|
||||
SnapInstallApp: 'Fazer backup dos aplicativos instalados do 1Panel'
|
||||
SnapInstallAppImageEmpty: 'Nenhuma imagem de aplicativo selecionada, pulando...'
|
||||
SnapInstallApp: 'Backup dos aplicativos instalados do 1Panel'
|
||||
SnapDockerSave: 'Compactar aplicativos instalados'
|
||||
SnapLocalBackup: 'Backup do diretório de backup local do 1Panel'
|
||||
SnapCompressBackup: 'Compactar diretório de backup local'
|
||||
|
||||
@@ -205,6 +205,8 @@ SystemLog: 'Системный лог'
|
||||
CutWebsiteLog: 'Ротация логов сайта'
|
||||
FileOrDir: 'Каталог / Файл'
|
||||
UploadFile: 'Загрузка файла резервной копии {{ .file }} в {{ .backup }}'
|
||||
IgnoreBackupErr: 'Ошибка резервного копирования: {{ .detail }}, игнорируем эту ошибку...'
|
||||
IgnoreUploadErr: 'Ошибка загрузки: {{ .detail }}, игнорируем эту ошибку...'
|
||||
|
||||
#ящик для инструментов
|
||||
ErrNotExistUser: 'Текущий пользователь не существует, измените его и повторите попытку!'
|
||||
@@ -333,7 +335,8 @@ SnapDeleteLoginLog: 'Удалить журнал доступа'
|
||||
SnapDeleteMonitor: 'Удалить данные мониторинга'
|
||||
SnapRemoveSystemIP: 'Удалить системный IP'
|
||||
SnapBaseInfo: 'Записать основную информацию 1Panel'
|
||||
SnapInstallApp: 'Резервное копирование установленных приложений 1Panel'
|
||||
SnapInstallAppImageEmpty: 'Образы приложений не выбраны, пропускаем...'
|
||||
SnapInstallApp: 'Резервное копирование приложений, установленных в 1Panel'
|
||||
SnapDockerSave: 'Сжать установленные приложения'
|
||||
SnapLocalBackup: 'Резервное копирование локального каталога резервных копий 1Panel'
|
||||
SnapCompressBackup: 'Сжать локальный каталог резервных копий'
|
||||
|
||||
@@ -204,6 +204,8 @@ SystemLog: '系統日誌'
|
||||
CutWebsiteLog: '切割網站日誌'
|
||||
FileOrDir: '目錄 / 檔案'
|
||||
UploadFile: '上傳備份文件 {{ .file }} 到 {{ .backup }}'
|
||||
IgnoreBackupErr: '備份失敗,錯誤:{{ .detail }},忽略本次錯誤...'
|
||||
IgnoreUploadErr: '上傳失敗,錯誤:{{ .detail }},忽略本次錯誤...'
|
||||
|
||||
#toolbox
|
||||
ErrNotExistUser: '目前使用者不存在,請修改後重試!'
|
||||
@@ -332,7 +334,8 @@ SnapDeleteLoginLog: '刪除存取日誌'
|
||||
SnapDeleteMonitor: '刪除監控資料'
|
||||
SnapRemoveSystemIP: '移除系統IP'
|
||||
SnapBaseInfo: '寫入1Panel 基本資料'
|
||||
SnapInstallApp: '備份1Panel 已安裝應用程式'
|
||||
SnapInstallAppImageEmpty: '當前未勾選應用鏡像,跳過...'
|
||||
SnapInstallApp: '備份 1Panel 已安裝應用'
|
||||
SnapDockerSave: '壓縮已安裝應用'
|
||||
SnapLocalBackup: '備份1Panel 本機備份目錄'
|
||||
SnapCompressBackup: '壓縮本機備份目錄'
|
||||
|
||||
@@ -204,6 +204,8 @@ SystemLog: "系统日志"
|
||||
CutWebsiteLog: "切割网站日志"
|
||||
FileOrDir: "目录 / 文件"
|
||||
UploadFile: "上传备份文件 {{ .file }} 到 {{ .backup }}"
|
||||
IgnoreBackupErr: "备份失败,错误:{{ .detail }},忽略本次错误..."
|
||||
IgnoreUploadErr: "上传失败,错误:{{ .detail }},忽略本次错误..."
|
||||
|
||||
#toolbox
|
||||
ErrNotExistUser: "当前用户不存在,请修改后重试!"
|
||||
@@ -332,6 +334,7 @@ SnapDeleteLoginLog: "删除访问日志"
|
||||
SnapDeleteMonitor: "删除监控数据"
|
||||
SnapRemoveSystemIP: "移除系统 IP"
|
||||
SnapBaseInfo: "写入 1Panel 基本信息"
|
||||
SnapInstallAppImageEmpty: "当前未勾选应用镜像,跳过..."
|
||||
SnapInstallApp: "备份 1Panel 已安装应用"
|
||||
SnapDockerSave: "压缩已安装应用"
|
||||
SnapLocalBackup: "备份 1Panel 本地备份目录"
|
||||
|
||||
+16
-5
@@ -2,12 +2,14 @@ package hook
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/dto"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/global"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
|
||||
)
|
||||
|
||||
@@ -18,6 +20,8 @@ func Init() {
|
||||
handleOllamaModelStatus()
|
||||
|
||||
loadLocalDir()
|
||||
|
||||
initDockerConf()
|
||||
}
|
||||
|
||||
func initGlobalData() {
|
||||
@@ -92,11 +96,7 @@ func handleCronJobAlert(cronjob *model.Cronjob) {
|
||||
EntryID: cronjob.ID,
|
||||
Param: cronjob.Type,
|
||||
}
|
||||
err := xpack.PushAlert(pushAlert)
|
||||
if err != nil {
|
||||
global.LOG.Errorf("cronjob alert push failed, err: %v", err)
|
||||
return
|
||||
}
|
||||
_ = xpack.PushAlert(pushAlert)
|
||||
}
|
||||
|
||||
func loadLocalDir() {
|
||||
@@ -113,3 +113,14 @@ func loadLocalDir() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initDockerConf() {
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashC("which docker")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dockerPath := stdout
|
||||
if strings.Contains(dockerPath, "snap") {
|
||||
constant.DaemonJsonPath = "/var/snap/docker/current/config/daemon.json"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ func InitAgentDB() {
|
||||
migrations.InitBackup,
|
||||
migrations.InitDefault,
|
||||
migrations.UpdateWebsiteExpireDate,
|
||||
migrations.UpdateRuntime,
|
||||
migrations.AddSnapshotRule,
|
||||
migrations.UpdatePHPRuntime,
|
||||
migrations.AddSnapshotIgnore,
|
||||
migrations.InitAppLauncher,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
||||
@@ -185,9 +185,6 @@ var InitSetting = &gormigrate.Migration{
|
||||
if err := tx.Create(&model.Setting{Key: "FileRecycleBin", Value: constant.StatusEnable}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: "SnapshotIgnore", Value: "*.sock"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := tx.Create(&model.Setting{Key: "LocalSSHConn", Value: ""}).Error; err != nil {
|
||||
return err
|
||||
@@ -314,3 +311,52 @@ var UpdateWebsiteExpireDate = &gormigrate.Migration{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var UpdateRuntime = &gormigrate.Migration{
|
||||
ID: "20250624-update-runtime",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(
|
||||
&model.Runtime{},
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
var AddSnapshotRule = &gormigrate.Migration{
|
||||
ID: "20250703-add-snapshot-rule",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(
|
||||
&model.Cronjob{},
|
||||
)
|
||||
},
|
||||
}
|
||||
var UpdatePHPRuntime = &gormigrate.Migration{
|
||||
ID: "20250702-update-php-runtime",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
service.HandleOldPHPRuntime()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
var AddSnapshotIgnore = &gormigrate.Migration{
|
||||
ID: "20250628-add-snapshot-ignore",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(
|
||||
&model.Snapshot{},
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
var InitAppLauncher = &gormigrate.Migration{
|
||||
ID: "20250702-init-app-launcher",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
launchers := []string{"openresty", "mysql", "halo", "redis", "maxkb", "wordpress"}
|
||||
for _, val := range launchers {
|
||||
var item model.AppLauncher
|
||||
_ = tx.Model(&model.AppLauncher{}).Where("key = ?", val).First(&item).Error
|
||||
if item.ID == 0 {
|
||||
item.Key = val
|
||||
_ = tx.Create(&item).Error
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -48,5 +48,7 @@ func (r *RuntimeRouter) InitRouter(Router *gin.RouterGroup) {
|
||||
groupRouter.GET("/supervisor/process/:id", baseApi.GetSupervisorProcess)
|
||||
groupRouter.POST("/supervisor/process", baseApi.OperateSupervisorProcess)
|
||||
groupRouter.POST("/supervisor/process/file", baseApi.OperateSupervisorProcessFile)
|
||||
|
||||
groupRouter.POST("/remark", baseApi.UpdateRuntimeRemark)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +57,9 @@ func (g *googleDriveClient) Delete(pathItem string) (bool, error) {
|
||||
if len(fileInfo.ID) == 0 {
|
||||
return false, fmt.Errorf("no such file %s", pathItem)
|
||||
}
|
||||
res, err := g.googleRequest("https://www.googleapis.com/drive/v3/files/"+fileInfo.ID, http.MethodDelete, nil, nil)
|
||||
if err != nil {
|
||||
if _, err = g.googleRequest("https://www.googleapis.com/drive/v3/files/"+fileInfo.ID, http.MethodDelete, nil, nil); err != nil {
|
||||
return false, err
|
||||
}
|
||||
fmt.Println(string(res))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -99,14 +97,51 @@ func (g *googleDriveClient) Upload(src, target string) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
uploadUrl := resp.Header().Get("location")
|
||||
if _, err := g.googleRequest(uploadUrl, http.MethodPut, func(req *resty.Request) {
|
||||
req.SetHeader("Content-Length", strconv.FormatInt(fileInfo.Size(), 10)).SetBody(file)
|
||||
}, nil); err != nil {
|
||||
return false, err
|
||||
|
||||
buf := make([]byte, 5*1024*1024)
|
||||
var offset int64 = 0
|
||||
for {
|
||||
n, err := file.Read(buf)
|
||||
if err != nil && err != io.EOF {
|
||||
return false, fmt.Errorf("read file failed, err: %v", err)
|
||||
}
|
||||
if n == 0 {
|
||||
break
|
||||
}
|
||||
chunk := buf[:n]
|
||||
start := offset
|
||||
end := offset + int64(n) - 1
|
||||
if err = uploadChunk(client, uploadUrl, chunk, start, end, fileInfo.Size()); err != nil {
|
||||
return false, err
|
||||
}
|
||||
offset += int64(n)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func uploadChunk(client *resty.Client, uploadURL string, chunk []byte, start, end, total int64) error {
|
||||
contentRange := fmt.Sprintf("bytes %d-%d/%d", start, end, total)
|
||||
|
||||
resp, err := client.R().
|
||||
SetHeader("Content-Length", strconv.Itoa(len(chunk))).
|
||||
SetHeader("Content-Range", contentRange).
|
||||
SetBody(chunk).
|
||||
Put(uploadURL)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("new request for upload chunk failed: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode() != 200 && resp.StatusCode() != 308 {
|
||||
return fmt.Errorf("upload chunk failed: %s, %s", resp.Status(), string(resp.Body()))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *googleDriveClient) Download(src, target string) (bool, error) {
|
||||
src = path.Join("/root", src)
|
||||
fileInfo, err := g.loadFileWithName(src)
|
||||
|
||||
+28
-18
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||
@@ -17,12 +18,13 @@ import (
|
||||
)
|
||||
|
||||
type CommandHelper struct {
|
||||
workDir string
|
||||
outputFile string
|
||||
scriptPath string
|
||||
timeout time.Duration
|
||||
taskItem *task.Task
|
||||
logger *log.Logger
|
||||
workDir string
|
||||
outputFile string
|
||||
scriptPath string
|
||||
timeout time.Duration
|
||||
taskItem *task.Task
|
||||
logger *log.Logger
|
||||
IgnoreExist1 bool
|
||||
}
|
||||
|
||||
type Option func(*CommandHelper)
|
||||
@@ -65,6 +67,7 @@ func (c *CommandHelper) RunBashCWithArgs(arg ...string) error {
|
||||
_, err := c.run("bash", arg...)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *CommandHelper) RunBashC(command string) error {
|
||||
std, err := c.run("bash", "-c", command)
|
||||
if err != nil {
|
||||
@@ -133,23 +136,17 @@ func (c *CommandHelper) run(name string, arg ...string) (string, error) {
|
||||
cmd.Dir = c.workDir
|
||||
}
|
||||
|
||||
err := cmd.Run()
|
||||
if c.taskItem != nil {
|
||||
customWriter.Flush()
|
||||
}
|
||||
if c.timeout != 0 {
|
||||
err := cmd.Run()
|
||||
if c.taskItem != nil {
|
||||
customWriter.Flush()
|
||||
}
|
||||
if ctx != nil && errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
return "", buserr.New("ErrCmdTimeout")
|
||||
}
|
||||
if err != nil {
|
||||
return handleErr(stdout, stderr, err)
|
||||
}
|
||||
return stdout.String(), nil
|
||||
}
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return handleErr(stdout, stderr, err)
|
||||
return handleErr(stdout, stderr, c.IgnoreExist1, err)
|
||||
}
|
||||
return stdout.String(), nil
|
||||
}
|
||||
@@ -184,6 +181,11 @@ func WithScriptPath(scriptPath string) Option {
|
||||
s.scriptPath = scriptPath
|
||||
}
|
||||
}
|
||||
func WithIgnoreExist1() Option {
|
||||
return func(s *CommandHelper) {
|
||||
s.IgnoreExist1 = true
|
||||
}
|
||||
}
|
||||
|
||||
type CustomWriter struct {
|
||||
taskItem *task.Task
|
||||
@@ -209,7 +211,15 @@ func (cw *CustomWriter) Flush() {
|
||||
}
|
||||
}
|
||||
|
||||
func handleErr(stdout, stderr bytes.Buffer, err error) (string, error) {
|
||||
func handleErr(stdout, stderr bytes.Buffer, ignoreExist1 bool, err error) (string, error) {
|
||||
var exitError *exec.ExitError
|
||||
if ignoreExist1 && errors.As(err, &exitError) {
|
||||
if status, ok := exitError.Sys().(syscall.WaitStatus); ok {
|
||||
if status.ExitStatus() == 1 {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
}
|
||||
errMsg := ""
|
||||
if len(stderr.String()) != 0 {
|
||||
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
|
||||
|
||||
@@ -31,7 +31,7 @@ func Down(filePath string) (string, error) {
|
||||
if err := checkCmd(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCf(global.CONF.DockerConfig.Command+" -f %s down --remove-orphans", filePath)
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCfAndTimeOut(global.CONF.DockerConfig.Command+" -f %s down --remove-orphans", 20*time.Minute, filePath)
|
||||
return stdout, err
|
||||
}
|
||||
|
||||
|
||||
@@ -329,25 +329,30 @@ func (f FileOp) DownloadFile(url, dst string) error {
|
||||
}
|
||||
|
||||
func (f FileOp) Cut(oldPaths []string, dst, name string, cover bool) error {
|
||||
for _, p := range oldPaths {
|
||||
var dstPath string
|
||||
if name != "" {
|
||||
dstPath = filepath.Join(dst, name)
|
||||
if f.Stat(dstPath) {
|
||||
dstPath = dst
|
||||
}
|
||||
} else {
|
||||
base := filepath.Base(p)
|
||||
dstPath = filepath.Join(dst, base)
|
||||
if len(oldPaths) == 0 {
|
||||
return nil
|
||||
}
|
||||
var dstPath string
|
||||
coverFlag := ""
|
||||
if name != "" {
|
||||
dstPath = filepath.Join(dst, name)
|
||||
if f.Stat(dstPath) {
|
||||
dstPath = dst
|
||||
}
|
||||
coverFlag := ""
|
||||
if cover {
|
||||
coverFlag = "-f"
|
||||
}
|
||||
|
||||
if err := cmd.RunDefaultBashCf(`mv %s '%s' '%s'`, coverFlag, p, dstPath); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
dstPath = dst
|
||||
coverFlag = "-f"
|
||||
}
|
||||
var quotedPaths []string
|
||||
for _, p := range oldPaths {
|
||||
quotedPaths = append(quotedPaths, fmt.Sprintf("'%s'", p))
|
||||
}
|
||||
mvCommand := fmt.Sprintf("mv %s %s '%s'", coverFlag, strings.Join(quotedPaths, " "), dstPath)
|
||||
if err := cmd.RunDefaultBashCf(mvCommand); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -810,6 +815,9 @@ func (f FileOp) TarGzCompressPro(withDir bool, src, dst, secret, exclusionRules
|
||||
if len(exclude) == 0 {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(exclude, "/") {
|
||||
exclude, _ = filepath.Rel(src, exclude)
|
||||
}
|
||||
if _, ok := exMap[exclude]; ok {
|
||||
continue
|
||||
}
|
||||
@@ -817,19 +825,14 @@ func (f FileOp) TarGzCompressPro(withDir bool, src, dst, secret, exclusionRules
|
||||
exMap[exclude] = struct{}{}
|
||||
}
|
||||
|
||||
itemPrefix := filepath.Base(src)
|
||||
if itemPrefix == "/" {
|
||||
itemPrefix = ""
|
||||
}
|
||||
if len(secret) != 0 {
|
||||
commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read %s --exclude-from=<(find %s -type s -printf '%s' | sed 's|^|%s/|') -zcf - %s | openssl enc -aes-256-cbc -salt -k '%s' -out %s", exStr, src, "%P\n", itemPrefix, srcItem, secret, dst)
|
||||
commands = fmt.Sprintf("tar %s -zcf - %s | openssl enc -aes-256-cbc -salt -k '%s' -out %s", exStr, srcItem, secret, dst)
|
||||
global.LOG.Debug(strings.ReplaceAll(commands, fmt.Sprintf(" %s ", secret), "******"))
|
||||
} else {
|
||||
commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read --exclude-from=<(find %s -type s -printf '%s' | sed 's|^|%s/|') -zcf %s %s %s", src, "%P\n", itemPrefix, dst, exStr, srcItem)
|
||||
commands = fmt.Sprintf("tar -zcf %s %s %s", dst, exStr, srcItem)
|
||||
global.LOG.Debug(commands)
|
||||
}
|
||||
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithWorkDir(workdir))
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithWorkDir(workdir), cmd.WithIgnoreExist1())
|
||||
return cmdMgr.RunBashC(commands)
|
||||
}
|
||||
|
||||
@@ -846,13 +849,14 @@ func (f FileOp) TarGzFilesWithCompressPro(list []string, dst, secret string) err
|
||||
}
|
||||
commands := ""
|
||||
if len(secret) != 0 {
|
||||
commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf - %s | openssl enc -aes-256-cbc -salt -k '%s' -out %s", strings.Join(filelist, " "), secret, dst)
|
||||
commands = fmt.Sprintf("tar -zcf - %s | openssl enc -aes-256-cbc -salt -k '%s' -out %s", strings.Join(filelist, " "), secret, dst)
|
||||
global.LOG.Debug(strings.ReplaceAll(commands, fmt.Sprintf(" %s ", secret), "******"))
|
||||
} else {
|
||||
commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf %s %s", dst, strings.Join(filelist, " "))
|
||||
commands = fmt.Sprintf("tar -zcf %s %s", dst, strings.Join(filelist, " "))
|
||||
global.LOG.Debug(commands)
|
||||
}
|
||||
return cmd.RunDefaultBashC(commands)
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithIgnoreExist1())
|
||||
return cmdMgr.RunBashC(commands)
|
||||
}
|
||||
|
||||
func (f FileOp) TarGzExtractPro(src, dst string, secret string) error {
|
||||
@@ -870,7 +874,7 @@ func (f FileOp) TarGzExtractPro(src, dst string, secret string) error {
|
||||
commands = fmt.Sprintf("tar zxvf %s", src)
|
||||
global.LOG.Debug(commands)
|
||||
}
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithWorkDir(dst))
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithWorkDir(dst), cmd.WithIgnoreExist1())
|
||||
return cmdMgr.RunBashC(commands)
|
||||
}
|
||||
func CopyCustomAppFile(srcPath, dstPath string) error {
|
||||
|
||||
@@ -7,6 +7,13 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
||||
"github.com/1Panel-dev/1Panel/agent/constant"
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
|
||||
"golang.org/x/text/encoding"
|
||||
"golang.org/x/text/encoding/charmap"
|
||||
"golang.org/x/text/encoding/japanese"
|
||||
"golang.org/x/text/encoding/korean"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/encoding/traditionalchinese"
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -201,3 +208,68 @@ func DownloadFileWithProxy(url, dst string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDecoderByName(name string) encoding.Encoding {
|
||||
switch strings.ToLower(name) {
|
||||
case "gbk":
|
||||
return simplifiedchinese.GBK
|
||||
case "gb18030":
|
||||
return simplifiedchinese.GB18030
|
||||
case "big5":
|
||||
return traditionalchinese.Big5
|
||||
case "euc-jp":
|
||||
return japanese.EUCJP
|
||||
case "iso-2022-jp":
|
||||
return japanese.ISO2022JP
|
||||
case "shift_jis":
|
||||
return japanese.ShiftJIS
|
||||
case "euc-kr":
|
||||
return korean.EUCKR
|
||||
case "utf-16be":
|
||||
return unicode.UTF16(unicode.BigEndian, unicode.ExpectBOM)
|
||||
case "utf-16le":
|
||||
return unicode.UTF16(unicode.LittleEndian, unicode.ExpectBOM)
|
||||
case "windows-1250":
|
||||
return charmap.Windows1250
|
||||
case "windows-1251":
|
||||
return charmap.Windows1251
|
||||
case "windows-1252":
|
||||
return charmap.Windows1252
|
||||
case "windows-1253":
|
||||
return charmap.Windows1253
|
||||
case "windows-1254":
|
||||
return charmap.Windows1254
|
||||
case "windows-1255":
|
||||
return charmap.Windows1255
|
||||
case "windows-1256":
|
||||
return charmap.Windows1256
|
||||
case "windows-1257":
|
||||
return charmap.Windows1257
|
||||
case "windows-1258":
|
||||
return charmap.Windows1258
|
||||
case "iso-8859-1":
|
||||
return charmap.ISO8859_1
|
||||
case "iso-8859-2":
|
||||
return charmap.ISO8859_2
|
||||
case "iso-8859-3":
|
||||
return charmap.ISO8859_3
|
||||
case "iso-8859-4":
|
||||
return charmap.ISO8859_4
|
||||
case "iso-8859-5":
|
||||
return charmap.ISO8859_5
|
||||
case "iso-8859-6":
|
||||
return charmap.ISO8859_6
|
||||
case "iso-8859-7":
|
||||
return charmap.ISO8859_7
|
||||
case "iso-8859-8":
|
||||
return charmap.ISO8859_8
|
||||
case "iso-8859-9":
|
||||
return charmap.ISO8859_9
|
||||
case "iso-8859-13":
|
||||
return charmap.ISO8859_13
|
||||
case "iso-8859-15":
|
||||
return charmap.ISO8859_15
|
||||
default:
|
||||
return encoding.Nop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package v2
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -185,26 +184,33 @@ func (b *BaseApi) RunScript(c *gin.Context) {
|
||||
tty.Start(quitChan)
|
||||
go slave.Wait(quitChan)
|
||||
} else {
|
||||
connInfo, installDir, err := xpack.LoadNodeInfo(currentNode)
|
||||
connInfo, _, err := xpack.LoadNodeInfo(currentNode)
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "invalid param rows in request")) {
|
||||
return
|
||||
}
|
||||
|
||||
fileDir := path.Join(installDir, "1panel/tmp/script")
|
||||
fileName := ""
|
||||
var translations = make(map[string]string)
|
||||
_ = json.Unmarshal([]byte(scriptItem.Name), &translations)
|
||||
if name, ok := translations["en"]; ok {
|
||||
fileName = path.Join(fileDir, strings.ReplaceAll(name, " ", "_"))
|
||||
fileName = strings.ReplaceAll(name, " ", "_")
|
||||
} else {
|
||||
fileName = path.Join(fileDir, strings.ReplaceAll(scriptItem.Name, " ", "_"))
|
||||
fileName = strings.ReplaceAll(scriptItem.Name, " ", "_")
|
||||
}
|
||||
initCmd := fmt.Sprintf("mkdir -p %s && cat > %s <<'MYMARKER'\n%s\nMYMARKER\n bash %s", fileDir, fileName, scriptItem.Script, fileName)
|
||||
client, err := ssh.NewClient(*connInfo)
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "failed to set up the connection. Please check the host information")) {
|
||||
if wshandleError(wsConn, errors.WithMessage(err, "set up the connection failed. Please check the host information")) {
|
||||
return
|
||||
}
|
||||
defer client.Close()
|
||||
sudoItem := client.SudoHandleCmd()
|
||||
defer func() {
|
||||
_, _ = client.Runf("%s rm -rf %s", sudoItem, fileName)
|
||||
client.Close()
|
||||
}()
|
||||
std, err := client.Runf("%s touch %s && %s chmod 777 %s && %s cat > %s <<'MYMARKER'\n%s\nMYMARKER\n", sudoItem, fileName, sudoItem, fileName, sudoItem, fileName, scriptItem.Script)
|
||||
if wshandleError(wsConn, errors.WithMessage(err, fmt.Sprintf("touch script file failed, err: %s. Please check and retry", std))) {
|
||||
return
|
||||
}
|
||||
initCmd := fmt.Sprintf("%s bash %s", sudoItem, fileName)
|
||||
|
||||
sws, err := terminal.NewLogicSshWsSession(cols, rows, client.Client, wsConn, initCmd)
|
||||
if wshandleError(wsConn, err) {
|
||||
|
||||
@@ -16,6 +16,7 @@ type IUpgradeLogRepo interface {
|
||||
Delete(opts ...global.DBOption) error
|
||||
|
||||
WithByNodeID(nodeID uint) global.DBOption
|
||||
WithByUpgradeVersion(oldVersion, newVersion string) global.DBOption
|
||||
}
|
||||
|
||||
func NewIUpgradeLogRepo() IUpgradeLogRepo {
|
||||
@@ -79,3 +80,9 @@ func (c *UpgradeLogRepo) WithByNodeID(nodeID uint) global.DBOption {
|
||||
return g.Where("node_id = ?", nodeID)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *UpgradeLogRepo) WithByUpgradeVersion(oldVersion, newVersion string) global.DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("old_version = ? AND new_version = ?", oldVersion, newVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,8 +268,6 @@ func (u *BackupService) RefreshToken(req dto.OperateByName) error {
|
||||
switch backup.Type {
|
||||
case constant.OneDrive:
|
||||
refreshToken, err = client.RefreshToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.GoogleDrive:
|
||||
refreshToken, err = client.RefreshGoogleToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.ALIYUN:
|
||||
refreshToken, err = client.RefreshALIToken(varMap)
|
||||
}
|
||||
|
||||
@@ -87,6 +87,12 @@ var restoreCmd = &cobra.Command{
|
||||
|
||||
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreStep5"))
|
||||
fmt.Println(i18n.GetMsgByKeyForCmd("RestoreSuccessful"))
|
||||
|
||||
_, _ = cmdUtils.RunDefaultWithStdoutBashC("systemctl daemon-reload")
|
||||
std, err := cmdUtils.RunDefaultWithStdoutBashC("1pctl restart all")
|
||||
if err != nil {
|
||||
fmt.Println(std)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
+142
-94
@@ -97,6 +97,13 @@
|
||||
"formatZH": "同步Ollama模型列表",
|
||||
"formatEN": "syncOllamamodellist"
|
||||
},
|
||||
"/apps/ignored/cancel": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "取消忽略应用升级",
|
||||
"formatEN": "Cancelignoreapplicationupgrade"
|
||||
},
|
||||
"/apps/install": {
|
||||
"bodyKeys": [
|
||||
"name"
|
||||
@@ -117,13 +124,11 @@
|
||||
"formatEN": "Applicationconfigupdate[installID]"
|
||||
},
|
||||
"/apps/installed/ignore": {
|
||||
"bodyKeys": [
|
||||
"installId"
|
||||
],
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "忽略应用[installId]版本升级",
|
||||
"formatEN": "Applicationparamupdate[installId]"
|
||||
"formatZH": "忽略应用升级",
|
||||
"formatEN": "Ignoreapplicationupgrade"
|
||||
},
|
||||
"/apps/installed/op": {
|
||||
"bodyKeys": [
|
||||
@@ -649,16 +654,6 @@
|
||||
"formatZH": "删除容器存储卷[names]",
|
||||
"formatEN": "deletecontainervolume[names]"
|
||||
},
|
||||
"/core/app/launcher/show": {
|
||||
"bodyKeys": [
|
||||
"key",
|
||||
"value"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "首页应用[key]=\u003e显示:[value]",
|
||||
"formatEN": "applauncher[key]=\u003eshow:[value]"
|
||||
},
|
||||
"/core/backups": {
|
||||
"bodyKeys": [
|
||||
"type"
|
||||
@@ -840,6 +835,13 @@
|
||||
"formatZH": "绑定许可证",
|
||||
"formatEN": "bindlicense"
|
||||
},
|
||||
"/core/licenses/bind/free": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "修改许可证免费节点绑定",
|
||||
"formatEN": "changebindoffreenodeforlicense"
|
||||
},
|
||||
"/core/licenses/del": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
@@ -1232,6 +1234,16 @@
|
||||
"formatZH": "更新计划任务[name]",
|
||||
"formatEN": "updatecronjob[name]"
|
||||
},
|
||||
"/dashboard/app/launcher/show": {
|
||||
"bodyKeys": [
|
||||
"key",
|
||||
"value"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "首页应用[key]=\u003e显示:[value]",
|
||||
"formatEN": "applauncher[key]=\u003eshow:[value]"
|
||||
},
|
||||
"/databases": {
|
||||
"bodyKeys": [
|
||||
"name"
|
||||
@@ -1568,6 +1580,15 @@
|
||||
"formatZH": "删除文件/文件夹[path]",
|
||||
"formatEN": "Deletedirorfile[path]"
|
||||
},
|
||||
"/files/depth/size": {
|
||||
"bodyKeys": [
|
||||
"path"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "获取目录及其第一层子目录文件夹大小[path]",
|
||||
"formatEN": "Multifilesize[path]"
|
||||
},
|
||||
"/files/favorite": {
|
||||
"bodyKeys": [
|
||||
"path"
|
||||
@@ -1672,12 +1693,13 @@
|
||||
},
|
||||
"/files/upload": {
|
||||
"bodyKeys": [
|
||||
"path"
|
||||
"path",
|
||||
"file"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "上传文件[path]",
|
||||
"formatEN": "Uploadfile[path]"
|
||||
"formatZH": "上传文件[path]/[file]",
|
||||
"formatEN": "Uploadfile[path]/[file]"
|
||||
},
|
||||
"/files/wget": {
|
||||
"bodyKeys": [
|
||||
@@ -1690,85 +1712,13 @@
|
||||
"formatZH": "下载url=\u003e[path]/[name]",
|
||||
"formatEN": "Downloadurl=\u003e[path]/[name]"
|
||||
},
|
||||
"/host/conffile/update": {
|
||||
"/hosts/conffile/update": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "修改SSH配置文件",
|
||||
"formatEN": "updateSSHconf"
|
||||
},
|
||||
"/host/ssh/generate": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "生成SSH密钥",
|
||||
"formatEN": "generateSSHsecret"
|
||||
},
|
||||
"/host/ssh/operate": {
|
||||
"bodyKeys": [
|
||||
"operation"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operation]SSH",
|
||||
"formatEN": "[operation]SSH"
|
||||
},
|
||||
"/host/ssh/update": {
|
||||
"bodyKeys": [
|
||||
"key",
|
||||
"value"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "修改SSH配置[key]=\u003e[value]",
|
||||
"formatEN": "updateSSHsetting[key]=\u003e[value]"
|
||||
},
|
||||
"/host/tool/config": {
|
||||
"bodyKeys": [
|
||||
"operate"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate]主机工具配置文件",
|
||||
"formatEN": "[operate]toolconfig"
|
||||
},
|
||||
"/host/tool/create": {
|
||||
"bodyKeys": [
|
||||
"type"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "创建[type]配置",
|
||||
"formatEN": "create[type]config"
|
||||
},
|
||||
"/host/tool/operate": {
|
||||
"bodyKeys": [
|
||||
"operate",
|
||||
"type"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate][type]",
|
||||
"formatEN": "[operate][type]"
|
||||
},
|
||||
"/host/tool/supervisor/process": {
|
||||
"bodyKeys": [
|
||||
"operate"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate]守护进程",
|
||||
"formatEN": "[operate]process"
|
||||
},
|
||||
"/host/tool/supervisor/process/file": {
|
||||
"bodyKeys": [
|
||||
"operate"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate]Supervisor进程文件",
|
||||
"formatEN": "[operate]SupervisorProcessConfigfile"
|
||||
},
|
||||
"/hosts/firewall/forward": {
|
||||
"bodyKeys": [
|
||||
"source_port"
|
||||
@@ -1824,6 +1774,78 @@
|
||||
"formatZH": "修改默认监控网卡[name]-[value]",
|
||||
"formatEN": "updatedefaultmonitor[name]-[value]"
|
||||
},
|
||||
"/hosts/ssh/generate": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "生成SSH密钥",
|
||||
"formatEN": "generateSSHsecret"
|
||||
},
|
||||
"/hosts/ssh/operate": {
|
||||
"bodyKeys": [
|
||||
"operation"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operation]SSH",
|
||||
"formatEN": "[operation]SSH"
|
||||
},
|
||||
"/hosts/ssh/update": {
|
||||
"bodyKeys": [
|
||||
"key",
|
||||
"value"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "修改SSH配置[key]=\u003e[value]",
|
||||
"formatEN": "updateSSHsetting[key]=\u003e[value]"
|
||||
},
|
||||
"/hosts/tool/config": {
|
||||
"bodyKeys": [
|
||||
"operate"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate]主机工具配置文件",
|
||||
"formatEN": "[operate]toolconfig"
|
||||
},
|
||||
"/hosts/tool/create": {
|
||||
"bodyKeys": [
|
||||
"type"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "创建[type]配置",
|
||||
"formatEN": "create[type]config"
|
||||
},
|
||||
"/hosts/tool/operate": {
|
||||
"bodyKeys": [
|
||||
"operate",
|
||||
"type"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate][type]",
|
||||
"formatEN": "[operate][type]"
|
||||
},
|
||||
"/hosts/tool/supervisor/process": {
|
||||
"bodyKeys": [
|
||||
"operate"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate]守护进程",
|
||||
"formatEN": "[operate]process"
|
||||
},
|
||||
"/hosts/tool/supervisor/process/file": {
|
||||
"bodyKeys": [
|
||||
"operate"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "[operate]Supervisor进程文件",
|
||||
"formatEN": "[operate]SupervisorProcessConfigfile"
|
||||
},
|
||||
"/openresty/build": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
@@ -1989,6 +2011,13 @@
|
||||
"formatZH": "删除脚本库脚本[names]",
|
||||
"formatEN": "deletescript[names]"
|
||||
},
|
||||
"/script/sync": {
|
||||
"bodyKeys": [],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "同步脚本库脚本",
|
||||
"formatEN": "syncscripts"
|
||||
},
|
||||
"/script/update": {
|
||||
"bodyKeys": [
|
||||
"id"
|
||||
@@ -2417,6 +2446,24 @@
|
||||
"formatZH": "删除网站acme[email]",
|
||||
"formatEN": "Deletewebsiteacme[email]"
|
||||
},
|
||||
"/websites/acme/update": {
|
||||
"bodyKeys": [
|
||||
"id"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [
|
||||
{
|
||||
"input_column": "id",
|
||||
"input_value": "id",
|
||||
"isList": false,
|
||||
"db": "website_acme_accounts",
|
||||
"output_column": "email",
|
||||
"output_value": "email"
|
||||
}
|
||||
],
|
||||
"formatZH": "更新acme[email]",
|
||||
"formatEN": "Updateacme[email]"
|
||||
},
|
||||
"/websites/ca": {
|
||||
"bodyKeys": [
|
||||
"name"
|
||||
@@ -3019,12 +3066,13 @@
|
||||
"/xpack/tampers/update": {
|
||||
"bodyKeys": [
|
||||
"website",
|
||||
"status"
|
||||
"status",
|
||||
"path"
|
||||
],
|
||||
"paramKeys": [],
|
||||
"beforeFunctions": [],
|
||||
"formatZH": "更新防篡改信息[website]=\u003e[status]",
|
||||
"formatEN": "updatetamperinfo[website]=\u003e[status]"
|
||||
"formatZH": "更新防篡改信息[website][path]=\u003e[status]",
|
||||
"formatEN": "updatetamperinfo[website][path]=\u003e[status]"
|
||||
},
|
||||
"/xpack/waf/acl/create": {
|
||||
"bodyKeys": [
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -33,8 +33,6 @@ const (
|
||||
|
||||
OneDriveRedirectURI = "http://localhost/login/authorized"
|
||||
GoogleRedirectURI = "https://localhost:8080"
|
||||
|
||||
DaemonJsonPath = "/etc/docker/daemon.json"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -76,10 +74,10 @@ var WebUrlMap = map[string]struct{}{
|
||||
"/containers/setting": {},
|
||||
"/containers/dashboard": {},
|
||||
|
||||
"/cronjobs": {},
|
||||
"/cronjobs/cronjob": {},
|
||||
"/cronjobs/library": {},
|
||||
"/cronjobs/operate": {},
|
||||
"/cronjobs": {},
|
||||
"/cronjobs/cronjob": {},
|
||||
"/cronjobs/library": {},
|
||||
"/cronjobs/cronjob/operate": {},
|
||||
|
||||
"/databases": {},
|
||||
"/databases/mysql": {},
|
||||
@@ -176,3 +174,5 @@ var DynamicRoutes = []string{
|
||||
}
|
||||
|
||||
var CertStore atomic.Value
|
||||
|
||||
var DaemonJsonPath = "/etc/docker/daemon.json"
|
||||
|
||||
+9
-8
@@ -48,7 +48,7 @@ require (
|
||||
golang.org/x/text v0.26.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/gorm v1.25.11
|
||||
gorm.io/gorm v1.30.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -65,7 +65,7 @@ require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||
github.com/glebarez/go-sqlite v1.22.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
@@ -99,6 +99,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mozillazg/go-httpheader v0.2.1 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
@@ -114,17 +115,17 @@ require (
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
|
||||
golang.org/x/image v0.28.0 // indirect
|
||||
golang.org/x/sync v0.15.0 // indirect
|
||||
golang.org/x/time v0.6.0 // indirect
|
||||
golang.org/x/tools v0.33.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gorm.io/driver/sqlite v1.4.4 // indirect
|
||||
modernc.org/libc v1.22.5 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/sqlite v1.23.1 // indirect
|
||||
modernc.org/libc v1.66.1 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
modernc.org/sqlite v1.38.0 // indirect
|
||||
)
|
||||
|
||||
+39
-21
@@ -97,8 +97,8 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
|
||||
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
|
||||
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
|
||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
@@ -202,8 +202,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
@@ -338,9 +338,8 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.74 h1:fTo/XlPBTSpo3BAMshlwKL5RspXRv9us5UeHEGYCFe0=
|
||||
@@ -357,6 +356,8 @@ github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew0
|
||||
github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E=
|
||||
github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ=
|
||||
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
|
||||
github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
@@ -380,7 +381,6 @@ github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdk
|
||||
github.com/qiniu/go-sdk/v7 v7.21.1 h1:D/IjVOlg5pTw0jeDjqTo6H5QM73Obb1AYfPOHmIFN+Q=
|
||||
github.com/qiniu/go-sdk/v7 v7.21.1/go.mod h1:8EM2awITynlem2VML2dXGHkMYP2UyECsGLOdp6yMpco=
|
||||
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
@@ -516,8 +516,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
|
||||
@@ -720,8 +720,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
||||
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -836,8 +836,8 @@ gorm.io/gorm v1.23.7/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.10/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg=
|
||||
gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
||||
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -845,14 +845,32 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
|
||||
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
|
||||
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||
modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
|
||||
modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
|
||||
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
|
||||
modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA=
|
||||
modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/goabi0 v0.0.3 h1:y81b9r3asCh6Xtse6Nz85aYGB0cG3M3U6222yap1KWI=
|
||||
modernc.org/goabi0 v0.0.3/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||
modernc.org/libc v1.66.1 h1:4uQsntXbVyAgrV+j6NhKvDiUypoJL48BWQx6sy9y8ok=
|
||||
modernc.org/libc v1.66.1/go.mod h1:AiZxInURfEJx516LqEaFcrC+X38rt9G7+8ojIXQKHbo=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI=
|
||||
modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
||||
@@ -58,6 +58,7 @@ ErrXpackExceptional: "This section is for professional edition, please sync lice
|
||||
ErrXpackOutOfDate: "Current license has expired, please import the license again in Panel Settings - License"
|
||||
ErrXpackLost: "License has reached the maximum retry count, please go to the [Panel Settings] [License] page and click the sync button manually to ensure the professional features work correctly"
|
||||
ErrDeviceLost: "Required files for license verification are missing, please check and try again!"
|
||||
ErrDeviceErr: "The current environment does not match the license import environment. Please edit the license and re-import!"
|
||||
ErrXpackTimeout: "Request timeout, network connection might be unstable, please try again later!"
|
||||
ErrUnbindMaster: "Detected nodes in node management, unable to unbind the current license, please remove nodes first and retry!"
|
||||
ErrFreeNodeLimit: "Community version node limit reached, please go to www.lxware.cn/1panel to purchase and retry!"
|
||||
|
||||
@@ -59,6 +59,7 @@ ErrXpackExceptional: "この部分はプロフェッショナル版機能です
|
||||
ErrXpackOutOfDate: "現在のライセンスは期限切れです、再度「パネル設定-ライセンス」画面でライセンスをインポートしてください"
|
||||
ErrXpackLost: "ライセンスの最大試行回数に達しました、「パネル設定」「ライセンス」ページに移動し、手動で同期ボタンをクリックして、プロフェッショナル版機能が正常に使用できることを確認してください"
|
||||
ErrDeviceLost: "ライセンス検証に必要なファイルが失われました。確認して再試行してください!"
|
||||
ErrDeviceErr: "現在の環境とライセンスのインポート環境が一致しません。ライセンスを編集して再度インポートしてください!"
|
||||
ErrXpackTimeout: "リクエストタイムアウト、ネットワーク接続が不安定な可能性があります。後で再試行してください!"
|
||||
ErrUnbindMaster: "ノード管理にノードが存在するため、現在のライセンスを解除できません。ノードを削除してから再試行してください!"
|
||||
ErrFreeNodeLimit: "コミュニティ版のノード数が無料上限に達しました、www.lxware.cn/1panel で購入して再試行してください!"
|
||||
|
||||
@@ -58,6 +58,7 @@ ErrXpackExceptional: "이 섹션은 프로페셔널 에디션 기능입니다.
|
||||
ErrXpackOutOfDate: "현재 라이선스가 만료되었습니다. 다시 [패널 설정]-[라이선스] 인터페이스에서 라이선스를 가져오세요."
|
||||
ErrXpackLost: "라이선스가 최대 재시도 횟수에 도달했습니다. [패널 설정][라이선스] 페이지로 이동하여 수동으로 동기화 버튼을 클릭하여 프로페셔널 기능을 정상적으로 사용할 수 있도록 하세요."
|
||||
ErrDeviceLost: "라이센스 검증에 필요한 파일이 누락되었습니다. 확인 후 다시 시도해 주세요!"
|
||||
ErrDeviceErr: "현재 환경이 라이선스 가져오기 환경과 일치하지 않습니다. 라이선스를 편집하고 다시 가져오십시오!"
|
||||
ErrXpackTimeout: "요청 시간 초과, 네트워크 연결이 불안정할 수 있습니다. 나중에 다시 시도해 주세요!"
|
||||
ErrUnbindMaster: "노드 관리 내에 노드가 존재함을 감지하였습니다. 현재 라이선스를 해제할 수 없습니다. 먼저 제거 후 다시 시도해 주세요!"
|
||||
ErrFreeNodeLimit: "커뮤니티 에디션 노드 수가 무료 한도에 도달하였습니다. www.lxware.cn/1panel 에서 구매 후 다시 시도해 주세요!"
|
||||
|
||||
@@ -58,6 +58,7 @@ ErrXpackExceptional: "Bahagian ini adalah fungsi profesional, sila selaraskan le
|
||||
ErrXpackOutOfDate: "Lesen semasa telah tamat tempoh, sila muatkan lesen baru di Tetapan Papan Pemuka."
|
||||
ErrXpackLost: "Lesen telah mencapai bilangan percubaan maksimum, sila ke [Tetapan Papan Pemuka][Lesen] dan klik butang penyelarasan secara manual."
|
||||
ErrDeviceLost: "Fail yang diperlukan untuk pengesahan lesen hilang, sila semak dan cuba lagi!"
|
||||
ErrDeviceErr: "Persekitaran semasa tidak sepadan dengan persekitaran import lesen. Sila edit lesen dan import semula!"
|
||||
ErrXpackTimeout: "Permintaan tamat masa, sambungan rangkaian mungkin tidak stabil, sila cuba lagi kemudian!"
|
||||
ErrUnbindMaster: "Terdapat nod dalam pengurusan nod, sila keluarkan dahulu dan cuba lagi!"
|
||||
ErrFreeNodeLimit: "Jumlah nod versi komuniti telah mencapai had percuma, sila lawati www.lxware.cn/1panel untuk pembelian!"
|
||||
|
||||
@@ -58,6 +58,7 @@ ErrXpackExceptional: "Esta parte é uma funcionalidade profissional, por favor s
|
||||
ErrXpackOutOfDate: "A licença atual expirou, por favor importe uma nova em Configurações do Painel - Licença."
|
||||
ErrXpackLost: "A licença atingiu o número máximo de tentativas, acesse [Configurações do Painel][Licença] e clique no botão de sincronização manual."
|
||||
ErrDeviceLost: "Arquivos necessários para a verificação da licença estão faltando, por favor verifique e tente novamente!"
|
||||
ErrDeviceErr: "O ambiente atual não corresponde ao ambiente de importação da licença. Por favor, edite a licença e reimporte!"
|
||||
ErrXpackTimeout: "Requisição expirou, a conexão de rede pode estar instável, por favor tente novamente mais tarde!"
|
||||
ErrUnbindMaster: "Foram encontrados nós na gestão de nós, remova-os primeiro e tente novamente!"
|
||||
ErrFreeNodeLimit: "O número de nós da versão comunitária atingiu o limite gratuito, por favor acesse www.lxware.cn/1panel para comprar!"
|
||||
|
||||
@@ -58,6 +58,7 @@ ErrXpackExceptional: "Эта часть доступна только в про
|
||||
ErrXpackOutOfDate: "Текущая лицензия истекла, повторно импортируйте лицензию в разделе Настройки панели - Лицензия."
|
||||
ErrXpackLost: "Лицензия достигла максимального количества попыток, перейдите в [Настройки панели][Лицензия] и нажмите кнопку синхронизации вручную."
|
||||
ErrDeviceLost: "Необходимые файлы для проверки лицензии отсутствуют, пожалуйста, проверьте и попробуйте снова!"
|
||||
ErrDeviceErr: "Текущая среда не соответствует среде импорта лицензии. Отредактируйте лицензию и повторите импорт!"
|
||||
ErrXpackTimeout: "Время ожидания запроса истекло, возможно нестабильное сетевое соединение, повторите попытку позже!"
|
||||
ErrUnbindMaster: "В управлении узлами обнаружены узлы, сначала удалите их и повторите попытку!"
|
||||
ErrFreeNodeLimit: "Количество узлов в версии сообщества достигло бесплатного лимита, посетите www.lxware.cn/1panel для покупки!"
|
||||
|
||||
@@ -58,6 +58,7 @@ ErrXpackExceptional: "該部分為專業版功能,請先在 面板設定-許
|
||||
ErrXpackOutOfDate: "目前許可證已過期,請重新在 面板設定-許可證 介面匯入許可證"
|
||||
ErrXpackLost: "許可證已達到最大重試次數,請進入【面板設定】【許可證】頁面手動點擊同步按鈕,以確保專業版功能正常使用"
|
||||
ErrDeviceLost: "許可證校驗必要檔案遺失,請檢查後重試!"
|
||||
ErrDeviceErr: "當前環境與許可證導入環境不一致,請編輯許可證重新導入!"
|
||||
ErrXpackTimeout: "請求超時,網路連接可能不穩定,請稍後再試!"
|
||||
ErrUnbindMaster: "檢測到節點管理內存在節點,無法解綁目前許可證,請先移除後重試!"
|
||||
ErrFreeNodeLimit: "社區版節點數量已達免費上限,請前往 www.lxware.cn/1panel 購買後重試!"
|
||||
|
||||
@@ -58,6 +58,7 @@ ErrXpackExceptional: "该部分为专业版功能,请先在 面板设置-许
|
||||
ErrXpackOutOfDate: "当前许可证已过期,请重新在 面板设置-许可证 界面导入许可证"
|
||||
ErrXpackLost: "许可证已达到最大重试次数,请进入【面板设置】【许可证】页面手动点击同步按钮,以确保专业版功能正常使用"
|
||||
ErrDeviceLost: "许可证校验必要文件丢失,请检查后重试!"
|
||||
ErrDeviceErr: "当前环境与许可证导入环境不一致,请编辑许可证重新导入!"
|
||||
ErrXpackTimeout: "请求超时,网络连接可能不稳定,请稍后再试!"
|
||||
ErrUnbindMaster: "检测到节点管理内存在专业版节点,无法解绑当前许可证,请先移除或解绑后重试!"
|
||||
ErrFreeNodeLimit: "社区版节点数量已达到免费上限,请前往 www.lxware.cn/1panel 购买后重试!"
|
||||
|
||||
@@ -40,8 +40,6 @@ func (b *backup) Run() {
|
||||
switch backupItem.Type {
|
||||
case constant.OneDrive:
|
||||
refreshToken, err = client.RefreshToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.GoogleDrive:
|
||||
refreshToken, err = client.RefreshGoogleToken("refresh_token", "refreshToken", varMap)
|
||||
case constant.ALIYUN:
|
||||
refreshToken, err = client.RefreshALIToken(varMap)
|
||||
}
|
||||
|
||||
+40
-20
@@ -32,43 +32,52 @@ func Init() {
|
||||
handleUserInfo(global.CONF.Base.ChangeUserInfo, settingRepo)
|
||||
|
||||
generateKey()
|
||||
initDockerConf()
|
||||
}
|
||||
|
||||
func handleUserInfo(tags string, settingRepo repo.ISettingRepo) {
|
||||
if len(tags) == 0 {
|
||||
return
|
||||
}
|
||||
settingMap := make(map[string]string)
|
||||
if tags == "use_existing" {
|
||||
settingMap["ServerPort"] = common.LoadParams("ORIGINAL_PORT")
|
||||
global.CONF.Conn.Port = settingMap["ServerPort"]
|
||||
settingMap["UserName"] = global.CONF.Base.Username
|
||||
settingMap["Password"] = global.CONF.Base.Password
|
||||
settingMap["SecurityEntrance"] = global.CONF.Conn.Entrance
|
||||
settingMap["SystemVersion"] = common.LoadParams("ORIGINAL_VERSION")
|
||||
global.CONF.Base.Version = settingMap["SystemVersion"]
|
||||
settingMap["Language"] = global.CONF.Base.Language
|
||||
}
|
||||
if tags == "all" {
|
||||
if err := settingRepo.Update("UserName", common.RandStrAndNum(10)); err != nil {
|
||||
global.LOG.Fatalf("init username before start failed, err: %v", err)
|
||||
}
|
||||
pass, _ := encrypt.StringEncrypt(common.RandStrAndNum(10))
|
||||
if err := settingRepo.Update("Password", pass); err != nil {
|
||||
global.LOG.Fatalf("init password before start failed, err: %v", err)
|
||||
}
|
||||
if err := settingRepo.Update("SecurityEntrance", common.RandStrAndNum(10)); err != nil {
|
||||
global.LOG.Fatalf("init entrance before start failed, err: %v", err)
|
||||
}
|
||||
return
|
||||
settingMap["UserName"] = common.RandStrAndNum(10)
|
||||
settingMap["Password"] = common.RandStrAndNum(10)
|
||||
settingMap["SecurityEntrance"] = common.RandStrAndNum(10)
|
||||
}
|
||||
if strings.Contains(global.CONF.Base.ChangeUserInfo, "username") {
|
||||
if err := settingRepo.Update("UserName", common.RandStrAndNum(10)); err != nil {
|
||||
global.LOG.Fatalf("init username before start failed, err: %v", err)
|
||||
}
|
||||
settingMap["UserName"] = common.RandStrAndNum(10)
|
||||
}
|
||||
if strings.Contains(global.CONF.Base.ChangeUserInfo, "password") {
|
||||
pass, _ := encrypt.StringEncrypt(common.RandStrAndNum(10))
|
||||
if err := settingRepo.Update("Password", pass); err != nil {
|
||||
global.LOG.Fatalf("init password before start failed, err: %v", err)
|
||||
}
|
||||
settingMap["Password"] = common.RandStrAndNum(10)
|
||||
}
|
||||
if strings.Contains(global.CONF.Base.ChangeUserInfo, "entrance") {
|
||||
if err := settingRepo.Update("SecurityEntrance", common.RandStrAndNum(10)); err != nil {
|
||||
global.LOG.Fatalf("init entrance before start failed, err: %v", err)
|
||||
settingMap["SecurityEntrance"] = common.RandStrAndNum(10)
|
||||
}
|
||||
for key, val := range settingMap {
|
||||
if len(val) == 0 {
|
||||
continue
|
||||
}
|
||||
if key == "Password" {
|
||||
val, _ = encrypt.StringEncrypt(val)
|
||||
}
|
||||
if err := settingRepo.Update(key, val); err != nil {
|
||||
global.LOG.Errorf("update %s before start failed, err: %v", key, err)
|
||||
}
|
||||
}
|
||||
|
||||
_, _ = cmd.RunDefaultWithStdoutBashCf("%s sed -i '/CHANGE_USER_INFO=%v/d' /usr/local/bin/1pctl", cmd.SudoHandleCmd(), global.CONF.Base.ChangeUserInfo)
|
||||
_, _ = cmd.RunDefaultWithStdoutBashCf("%s sed -i -e 's#ORIGINAL_PASSWORD=.*#ORIGINAL_PASSWORD=**********#g' /usr/local/bin/1pctl", cmd.SudoHandleCmd())
|
||||
}
|
||||
|
||||
func generateKey() {
|
||||
@@ -76,3 +85,14 @@ func generateKey() {
|
||||
global.LOG.Errorf("generate rsa key error : %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func initDockerConf() {
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashC("which docker")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
dockerPath := stdout
|
||||
if strings.Contains(dockerPath, "snap") {
|
||||
constant.DaemonJsonPath = "/var/snap/docker/current/config/daemon.json"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ func Init() {
|
||||
migrations.AddXpackHideMenu,
|
||||
migrations.UpdateGoogle,
|
||||
migrations.UpdateXpackHideMenu,
|
||||
migrations.UpdateOnedrive,
|
||||
})
|
||||
if err := m.Migrate(); err != nil {
|
||||
global.LOG.Error(err)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/1Panel-dev/1Panel/core/init/migration/helper"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/common"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/encrypt"
|
||||
"github.com/go-gormigrate/gormigrate/v2"
|
||||
@@ -52,6 +53,7 @@ var InitSetting = &gormigrate.Migration{
|
||||
if err := tx.Create(&model.Setting{Key: "Password", Value: pass}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = cmd.RunDefaultWithStdoutBashCf("%s sed -i -e 's#ORIGINAL_PASSWORD=.*#ORIGINAL_PASSWORD=**********#g' /usr/local/bin/1pctl", cmd.SudoHandleCmd())
|
||||
if err := tx.Create(&model.Setting{Key: "Theme", Value: "light"}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -470,3 +472,20 @@ var UpdateGoogle = &gormigrate.Migration{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var UpdateOnedrive = &gormigrate.Migration{
|
||||
ID: "20250704-update-onedrive",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.Model(&model.Setting{}).
|
||||
Where("key = ?", "OneDriveID").
|
||||
Update("value", "NTQ0NmNmZTMtNGM3OS00N2EwLWFlMjUtZmM2NDU0NzhlMmQ5").Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Model(&model.Setting{}).
|
||||
Where("key = ?", "OneDriveSc").
|
||||
Update("value", "bGRlOFF+WEVrR1M0b25Vb1VsRWpMYzE2MW9rTXZEM25KdnZ1MGN6MA==").Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/1Panel-dev/1Panel/core/cmd/server/conf"
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/cmd"
|
||||
"github.com/1Panel-dev/1Panel/core/utils/common"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v3"
|
||||
@@ -39,13 +40,13 @@ func Init() {
|
||||
panic(fmt.Errorf("Fatal error config file: %s \n", err))
|
||||
}
|
||||
} else {
|
||||
baseDir = loadParams("BASE_DIR")
|
||||
port = loadParams("ORIGINAL_PORT")
|
||||
version = loadParams("ORIGINAL_VERSION")
|
||||
username = loadParams("ORIGINAL_USERNAME")
|
||||
password = loadParams("ORIGINAL_PASSWORD")
|
||||
entrance = loadParams("ORIGINAL_ENTRANCE")
|
||||
language = loadParams("LANGUAGE")
|
||||
baseDir = common.LoadParams("BASE_DIR")
|
||||
port = common.LoadParams("ORIGINAL_PORT")
|
||||
version = common.LoadParams("ORIGINAL_VERSION")
|
||||
username = common.LoadParams("ORIGINAL_USERNAME")
|
||||
password = common.LoadParams("ORIGINAL_PASSWORD")
|
||||
entrance = common.LoadParams("ORIGINAL_ENTRANCE")
|
||||
language = common.LoadParams("LANGUAGE")
|
||||
|
||||
reader := bytes.NewReader(conf.AppYaml)
|
||||
if err := v.ReadConfig(reader); err != nil {
|
||||
@@ -100,18 +101,6 @@ func Init() {
|
||||
global.Viper = v
|
||||
}
|
||||
|
||||
func loadParams(param string) string {
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCf("grep '^%s=' /usr/local/bin/1pctl | cut -d'=' -f2", param)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
info := strings.ReplaceAll(stdout, "\n", "")
|
||||
if len(info) == 0 || info == `""` {
|
||||
panic(fmt.Sprintf("error `%s` find in /usr/local/bin/1pctl", param))
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
func loadChangeInfo() string {
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashC("grep '^CHANGE_USER_INFO=' /usr/local/bin/1pctl | cut -d'=' -f2")
|
||||
if err != nil {
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -65,7 +67,11 @@ func OperationLog() gin.HandlerFunc {
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(body))
|
||||
}
|
||||
bodyMap := make(map[string]interface{})
|
||||
_ = json.Unmarshal(body, &bodyMap)
|
||||
if strings.Contains(c.Request.Header.Get("Content-Type"), "multipart/form-data") {
|
||||
bodyMap, _ = parseMultipart(body, c.Request.Header.Get("Content-Type"))
|
||||
} else {
|
||||
_ = json.Unmarshal(body, &bodyMap)
|
||||
}
|
||||
for _, key := range operationDic.BodyKeys {
|
||||
if _, ok := bodyMap[key]; ok {
|
||||
formatMap[key] = bodyMap[key]
|
||||
@@ -247,3 +253,33 @@ func replaceStr(val string, rep ...string) string {
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func parseMultipart(formData []byte, contentType string) (map[string]interface{}, error) {
|
||||
d, params, err := mime.ParseMediaType(contentType)
|
||||
if err != nil || d != "multipart/form-data" {
|
||||
return nil, http.ErrNotMultipart
|
||||
}
|
||||
boundary, ok := params["boundary"]
|
||||
if !ok {
|
||||
return nil, http.ErrMissingBoundary
|
||||
}
|
||||
reader := multipart.NewReader(bytes.NewReader(formData), boundary)
|
||||
ret := make(map[string]interface{})
|
||||
|
||||
f, err := reader.ReadForm(32 << 20)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range f.Value {
|
||||
if len(v) > 0 {
|
||||
ret[k] = v[0]
|
||||
}
|
||||
}
|
||||
for k, v := range f.File {
|
||||
if len(v) > 0 {
|
||||
ret[k] = v[0].Filename
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
+24
-9
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/app/task"
|
||||
@@ -17,12 +18,13 @@ import (
|
||||
)
|
||||
|
||||
type CommandHelper struct {
|
||||
workDir string
|
||||
outputFile string
|
||||
scriptPath string
|
||||
timeout time.Duration
|
||||
taskItem *task.Task
|
||||
logger *log.Logger
|
||||
workDir string
|
||||
outputFile string
|
||||
scriptPath string
|
||||
timeout time.Duration
|
||||
taskItem *task.Task
|
||||
logger *log.Logger
|
||||
IgnoreExist1 bool
|
||||
}
|
||||
|
||||
type Option func(*CommandHelper)
|
||||
@@ -132,14 +134,14 @@ func (c *CommandHelper) run(name string, arg ...string) (string, error) {
|
||||
return "", buserr.New("ErrCmdTimeout")
|
||||
}
|
||||
if err != nil {
|
||||
return handleErr(stdout, stderr, err)
|
||||
return handleErr(stdout, stderr, c.IgnoreExist1, err)
|
||||
}
|
||||
return stdout.String(), nil
|
||||
}
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return handleErr(stdout, stderr, err)
|
||||
return handleErr(stdout, stderr, c.IgnoreExist1, err)
|
||||
}
|
||||
return stdout.String(), nil
|
||||
}
|
||||
@@ -174,6 +176,11 @@ func WithScriptPath(scriptPath string) Option {
|
||||
s.scriptPath = scriptPath
|
||||
}
|
||||
}
|
||||
func WithIgnoreExist1() Option {
|
||||
return func(s *CommandHelper) {
|
||||
s.IgnoreExist1 = true
|
||||
}
|
||||
}
|
||||
|
||||
type CustomWriter struct {
|
||||
taskItem *task.Task
|
||||
@@ -199,7 +206,15 @@ func (cw *CustomWriter) Flush() {
|
||||
}
|
||||
}
|
||||
|
||||
func handleErr(stdout, stderr bytes.Buffer, err error) (string, error) {
|
||||
func handleErr(stdout, stderr bytes.Buffer, ignoreExist1 bool, err error) (string, error) {
|
||||
var exitError *exec.ExitError
|
||||
if ignoreExist1 && errors.As(err, &exitError) {
|
||||
if status, ok := exitError.Sys().(syscall.WaitStatus); ok {
|
||||
if status.ExitStatus() == 1 {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
}
|
||||
errMsg := ""
|
||||
if len(stderr.String()) != 0 {
|
||||
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
|
||||
|
||||
@@ -4,14 +4,12 @@ import (
|
||||
"fmt"
|
||||
mathRand "math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/constant"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/core/global"
|
||||
@@ -225,13 +223,14 @@ func HandleIPList(content string) ([]string, error) {
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func deleteCookie(w http.ResponseWriter) {
|
||||
cookie := &http.Cookie{
|
||||
Name: constant.SessionName,
|
||||
Value: "",
|
||||
Path: "/",
|
||||
Expires: time.Unix(0, 0),
|
||||
MaxAge: -1,
|
||||
func LoadParams(param string) string {
|
||||
stdout, err := cmd.RunDefaultWithStdoutBashCf("grep '^%s=' /usr/local/bin/1pctl | cut -d'=' -f2", param)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
http.SetCookie(w, cookie)
|
||||
info := strings.ReplaceAll(stdout, "\n", "")
|
||||
if len(info) == 0 || info == `""` {
|
||||
panic(fmt.Sprintf("error `%s` find in /usr/local/bin/1pctl", param))
|
||||
}
|
||||
return info
|
||||
}
|
||||
|
||||
@@ -83,7 +83,6 @@ func HandleTar(sourceDir, targetDir, name, exclusionRules string, secret string)
|
||||
exMap := make(map[string]struct{})
|
||||
excludes := strings.Split(exclusionRules, ",")
|
||||
excludeRules := ""
|
||||
excludes = append(excludes, "*.sock")
|
||||
for _, exclude := range excludes {
|
||||
if len(exclude) == 0 {
|
||||
continue
|
||||
@@ -110,13 +109,13 @@ func HandleTar(sourceDir, targetDir, name, exclusionRules string, secret string)
|
||||
|
||||
if len(secret) != 0 {
|
||||
extraCmd := "| openssl enc -aes-256-cbc -salt -k '" + secret + "' -out"
|
||||
commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf %s %s %s %s", " -"+excludeRules, path, extraCmd, targetDir+"/"+name)
|
||||
commands = fmt.Sprintf("tar -zcf %s %s %s %s", " -"+excludeRules, path, extraCmd, targetDir+"/"+name)
|
||||
global.LOG.Debug(strings.ReplaceAll(commands, fmt.Sprintf(" %s ", secret), "******"))
|
||||
} else {
|
||||
commands = fmt.Sprintf("tar --warning=no-file-changed --ignore-failed-read -zcf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
||||
commands = fmt.Sprintf("tar -zcf %s %s %s", targetDir+"/"+name, excludeRules, path)
|
||||
global.LOG.Debug(commands)
|
||||
}
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(24 * time.Hour))
|
||||
cmdMgr := cmd.NewCommandMgr(cmd.WithTimeout(24*time.Hour), cmd.WithIgnoreExist1())
|
||||
stdout, err := cmdMgr.RunWithStdoutBashC(commands)
|
||||
if err != nil {
|
||||
if len(stdout) != 0 {
|
||||
|
||||
@@ -75,6 +75,14 @@ func (c *SSHClient) SudoHandleCmd() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *SSHClient) IsRoot(user string) bool {
|
||||
if user == "root" {
|
||||
return true
|
||||
}
|
||||
_, err := c.Run("sudo -n true")
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (c *SSHClient) Runf(shell string, args ...interface{}) (string, error) {
|
||||
session, err := c.Client.NewSession()
|
||||
if err != nil {
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/2462" target="_blank"><img src="https://trendshift.io/api/badge/repositories/2462" alt="1Panel-dev%2F1Panel | Trendshift" style="width: 180px; height: auto;" /></a>
|
||||
<a href="https://hellogithub.com/repository/71791baf930149ac9b84e1acf186573f" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=71791baf930149ac9b84e1acf186573f&claim_uid=p8vB3kP5CMrthiL&theme=dark&theme=neutral" alt="Featured|HelloGitHub" style="width: 180px; height: auto;" /></a>
|
||||
<a href="https://market.aliyun.com/products/53690006/cmjj00062740.html?userCode=kmemb8jp" target="_blank"><img src="https://img.alicdn.com/imgextra/i2/O1CN01H5JIwY1rZ0OobDjnJ_!!6000000005644-2-tps-1000-216.png" alt="1Panel-dev%2F1Panel | Aliyun" style="width: 180px; height: auto;" /></a>
|
||||
</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?color=%231890FF" 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="GitHub Stars"></a>
|
||||
<a href="https://gitee.com/fit2cloud-feizhiyun/1Panel"><img src="https://gitee.com/fit2cloud-feizhiyun/1Panel/badge/star.svg?theme=gvp" alt="Gitee Stars"></a><br>
|
||||
<a href="https://gitee.com/fit2cloud-feizhiyun/1Panel"><img src="https://gitee.com/fit2cloud-feizhiyun/1Panel/badge/star.svg?theme=gvp" alt="Gitee Stars"></a>
|
||||
<a href="https://gitcode.com/feizhiyun/1Panel"><img src="https://gitcode.com/feizhiyun/1Panel/star/badge.svg" alt="GitCode Stars"></a><br>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="/README.md"><img alt="English" src="https://img.shields.io/badge/English-d9d9d9"></a>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"codemirror": "^6.0.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"echarts": "^5.5.0",
|
||||
"element-plus": "^2.9.9",
|
||||
"element-plus": "2.9.8",
|
||||
"fit2cloud-ui-plus": "^1.2.2",
|
||||
"highlight.js": "^11.9.0",
|
||||
"js-base64": "^3.7.7",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -47,7 +47,6 @@ class RequestHttp {
|
||||
|
||||
this.service.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
globalStore.errStatus = '';
|
||||
const { data } = response;
|
||||
if (data.code == ResultEnum.OVERDUE || data.code == ResultEnum.FORBIDDEN) {
|
||||
globalStore.setLogStatus(false);
|
||||
@@ -94,9 +93,9 @@ class RequestHttp {
|
||||
return data;
|
||||
},
|
||||
async (error: AxiosError) => {
|
||||
globalStore.errStatus = '';
|
||||
const { response } = error;
|
||||
if (error.message.indexOf('timeout') !== -1) MsgError('请求超时!请您稍后重试');
|
||||
|
||||
if (error.message.indexOf('timeout') !== -1) MsgError(i18n.global.t('commons.msg.requestTimeout'));
|
||||
if (response) {
|
||||
switch (response.status) {
|
||||
case 313:
|
||||
@@ -110,11 +109,6 @@ class RequestHttp {
|
||||
);
|
||||
return Promise.reject(error);
|
||||
default:
|
||||
globalStore.errStatus = 'code-' + response.status;
|
||||
router.push({
|
||||
name: 'entrance',
|
||||
params: { code: globalStore.entrance },
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user