mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-10-09 23:17:21 +08:00
feat: 应用升级增加日志 (#6011)
Some checks failed
sync2gitee / repo-sync (push) Failing after -7m21s
Some checks failed
sync2gitee / repo-sync (push) Failing after -7m21s
This commit is contained in:
parent
bdece10868
commit
25b189069c
17 changed files with 156 additions and 123 deletions
|
@ -72,6 +72,7 @@ type AppInstalledOperate struct {
|
|||
Backup bool `json:"backup"`
|
||||
PullImage bool `json:"pullImage"`
|
||||
DockerCompose string `json:"dockerCompose"`
|
||||
TaskID string `json:"taskID"`
|
||||
}
|
||||
|
||||
type AppInstallUpgrade struct {
|
||||
|
@ -80,6 +81,7 @@ type AppInstallUpgrade struct {
|
|||
Backup bool `json:"backup"`
|
||||
PullImage bool `json:"pullImage"`
|
||||
DockerCompose string `json:"dockerCompose"`
|
||||
TaskID string `json:"taskID"`
|
||||
}
|
||||
|
||||
type AppInstalledUpdate struct {
|
||||
|
|
|
@ -128,8 +128,13 @@ type FileReadByLineReq struct {
|
|||
ID uint `json:"ID"`
|
||||
Name string `json:"name"`
|
||||
Latest bool `json:"latest"`
|
||||
TaskID string `json:"taskID"`
|
||||
TaskType string `json:"taskType"`
|
||||
TaskReq
|
||||
}
|
||||
|
||||
type TaskReq struct {
|
||||
TaskID string `json:"taskID"`
|
||||
TaskType string `json:"taskType"`
|
||||
TaskOperate string `json:"taskOperate"`
|
||||
}
|
||||
|
||||
type FileExistReq struct {
|
||||
|
|
|
@ -6,6 +6,7 @@ type Task struct {
|
|||
ID string `gorm:"primarykey;" json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Operate string `json:"operate"`
|
||||
LogFile string `json:"logFile"`
|
||||
Status string `json:"status"`
|
||||
ErrorMsg string `json:"errorMsg"`
|
||||
|
|
|
@ -19,6 +19,7 @@ type ITaskRepo interface {
|
|||
WithType(taskType string) DBOption
|
||||
WithResourceID(id uint) DBOption
|
||||
WithStatus(status string) DBOption
|
||||
WithOperate(taskOperate string) DBOption
|
||||
}
|
||||
|
||||
func NewITaskRepo() ITaskRepo {
|
||||
|
@ -37,6 +38,12 @@ func (t TaskRepo) WithType(taskType string) DBOption {
|
|||
}
|
||||
}
|
||||
|
||||
func (t TaskRepo) WithOperate(taskOperate string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("operate = ?", taskOperate)
|
||||
}
|
||||
}
|
||||
|
||||
func (t TaskRepo) WithStatus(status string) DBOption {
|
||||
return func(g *gorm.DB) *gorm.DB {
|
||||
return g.Where("status = ?", status)
|
||||
|
|
|
@ -185,7 +185,7 @@ func (a AppService) GetAppDetail(appID uint, version, appType string) (response.
|
|||
|
||||
versionPath := filepath.Join(app.GetAppResourcePath(), detail.Version)
|
||||
if !fileOp.Stat(versionPath) || detail.Update {
|
||||
if err = downloadApp(app, detail, nil); err != nil {
|
||||
if err = downloadApp(app, detail, nil, nil); err != nil {
|
||||
return appDetailDTO, err
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ func (a AppService) Install(req request.AppInstallCreate) (appInstall *model.App
|
|||
return
|
||||
}
|
||||
|
||||
installTask, err := task.NewTaskWithOps(appInstall.Name, task.TaskCreate, task.TaskScopeApp, req.TaskID, appInstall.ID)
|
||||
installTask, err := task.NewTaskWithOps(appInstall.Name, task.TaskInstall, task.TaskScopeApp, req.TaskID, appInstall.ID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ func (a AppService) Install(req request.AppInstallCreate) (appInstall *model.App
|
|||
return nil
|
||||
}
|
||||
|
||||
handleAppStatus := func() {
|
||||
handleAppStatus := func(t *task.Task) {
|
||||
appInstall.Status = constant.UpErr
|
||||
appInstall.Message = installTask.Task.ErrorMsg
|
||||
_ = appInstallRepo.Save(context.Background(), appInstall)
|
||||
|
|
|
@ -272,6 +272,7 @@ func (a *AppInstallService) Operate(req request.AppInstalledOperate) error {
|
|||
Backup: req.Backup,
|
||||
PullImage: req.PullImage,
|
||||
DockerCompose: req.DockerCompose,
|
||||
TaskID: req.TaskID,
|
||||
}
|
||||
return upgradeInstall(upgradeReq)
|
||||
case constant.Reload:
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/1Panel-dev/1Panel/agent/app/task"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
|
@ -132,7 +133,7 @@ var ToolKeys = map[string]uint{
|
|||
}
|
||||
|
||||
func createLink(ctx context.Context, installTask *task.Task, app model.App, appInstall *model.AppInstall, params map[string]interface{}) error {
|
||||
deleteAppLink := func() {
|
||||
deleteAppLink := func(t *task.Task) {
|
||||
_ = deleteLink(ctx, appInstall, true, true, true)
|
||||
}
|
||||
var dbConfig dto.AppDatabase
|
||||
|
@ -496,67 +497,44 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
|||
if install.Version == detail.Version {
|
||||
return errors.New("two version is same")
|
||||
}
|
||||
|
||||
upgradeTask, err := task.NewTaskWithOps(install.Name, task.TaskUpgrade, task.TaskScopeApp, req.TaskID, install.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
install.Status = constant.Upgrading
|
||||
|
||||
go func() {
|
||||
var (
|
||||
upErr error
|
||||
backupFile string
|
||||
preErr error
|
||||
)
|
||||
global.LOG.Infof(i18n.GetMsgWithName("UpgradeAppStart", install.Name, nil))
|
||||
var (
|
||||
upErr error
|
||||
backupFile string
|
||||
)
|
||||
backUpApp := func(t *task.Task) error {
|
||||
if req.Backup {
|
||||
backupRecord, err := NewIBackupService().AppBackup(dto.CommonBackup{Name: install.App.Key, DetailName: install.Name})
|
||||
if err == nil {
|
||||
localDir, err := loadLocalDir()
|
||||
if err == nil {
|
||||
backupFile = path.Join(localDir, backupRecord.FileDir, backupRecord.FileName)
|
||||
} else {
|
||||
global.LOG.Errorf(i18n.GetMsgWithName("ErrAppBackup", install.Name, err))
|
||||
}
|
||||
} else {
|
||||
global.LOG.Errorf(i18n.GetMsgWithName("ErrAppBackup", install.Name, err))
|
||||
if err != nil {
|
||||
return buserr.WithNameAndErr("ErrAppBackup", install.Name, err)
|
||||
}
|
||||
localDir, err := loadLocalDir()
|
||||
if err != nil {
|
||||
return buserr.WithNameAndErr("ErrAppBackup", install.Name, err)
|
||||
}
|
||||
backupFile = path.Join(localDir, backupRecord.FileDir, backupRecord.FileName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
upgradeTask.AddSubTask(task.GetTaskName(install.Name, task.TaskBackup, task.TaskScopeApp), backUpApp, nil)
|
||||
|
||||
defer func() {
|
||||
if upErr != nil {
|
||||
global.LOG.Infof(i18n.GetMsgWithName("ErrAppUpgrade", install.Name, upErr))
|
||||
if req.Backup {
|
||||
global.LOG.Infof(i18n.GetMsgWithName("AppRecover", install.Name, nil))
|
||||
if err := NewIBackupService().AppRecover(dto.CommonRecover{Name: install.App.Key, DetailName: install.Name, Type: "app", Source: constant.ResourceLocal, File: backupFile}); err != nil {
|
||||
global.LOG.Errorf("recover app [%s] [%s] failed %v", install.App.Key, install.Name, err)
|
||||
}
|
||||
}
|
||||
existInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallID))
|
||||
if existInstall.ID > 0 {
|
||||
existInstall.Status = constant.UpgradeErr
|
||||
existInstall.Message = upErr.Error()
|
||||
_ = appInstallRepo.Save(context.Background(), &existInstall)
|
||||
}
|
||||
}
|
||||
if preErr != nil {
|
||||
global.LOG.Infof(i18n.GetMsgWithName("ErrAppUpgrade", install.Name, preErr))
|
||||
existInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallID))
|
||||
if existInstall.ID > 0 {
|
||||
existInstall.Status = constant.UpgradeErr
|
||||
existInstall.Message = preErr.Error()
|
||||
_ = appInstallRepo.Save(context.Background(), &existInstall)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
upgradeApp := func(t *task.Task) error {
|
||||
fileOp := files.NewFileOp()
|
||||
detailDir := path.Join(constant.ResourceDir, "apps", install.App.Resource, install.App.Key, detail.Version)
|
||||
if install.App.Resource == constant.AppResourceRemote {
|
||||
if preErr = downloadApp(install.App, detail, &install); preErr != nil {
|
||||
return
|
||||
if err = downloadApp(install.App, detail, &install, t.Logger); err != nil {
|
||||
return err
|
||||
}
|
||||
if detail.DockerCompose == "" {
|
||||
composeDetail, err := fileOp.GetContent(path.Join(detailDir, "docker-compose.yml"))
|
||||
if err != nil {
|
||||
preErr = err
|
||||
return
|
||||
return err
|
||||
}
|
||||
detail.DockerCompose = string(composeDetail)
|
||||
_ = appDetailRepo.Update(context.Background(), detail)
|
||||
|
@ -565,41 +543,37 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
|||
_, _, _ = httpUtil.HandleGet(detail.DownloadCallBackUrl, http.MethodGet, constant.TimeOut5s)
|
||||
}()
|
||||
}
|
||||
|
||||
if install.App.Resource == constant.AppResourceLocal {
|
||||
detailDir = path.Join(constant.ResourceDir, "apps", "local", strings.TrimPrefix(install.App.Key, "local"), detail.Version)
|
||||
}
|
||||
|
||||
content, err := fileOp.GetContent(install.GetEnvPath())
|
||||
if err != nil {
|
||||
preErr = err
|
||||
return
|
||||
return err
|
||||
}
|
||||
if req.PullImage {
|
||||
projectName := strings.ToLower(install.Name)
|
||||
images, err := composeV2.GetDockerComposeImages(projectName, content, []byte(detail.DockerCompose))
|
||||
if err != nil {
|
||||
preErr = err
|
||||
return
|
||||
return err
|
||||
}
|
||||
for _, image := range images {
|
||||
global.LOG.Infof(i18n.GetMsgWithName("PullImageStart", image, nil))
|
||||
t.Log(i18n.GetWithName("PullImageStart", image))
|
||||
if out, err := cmd.ExecWithTimeOut("docker pull "+image, 20*time.Minute); err != nil {
|
||||
if out != "" {
|
||||
err = errors.New(out)
|
||||
}
|
||||
preErr = buserr.WithNameAndErr("ErrDockerPullImage", "", err)
|
||||
return
|
||||
} else {
|
||||
global.LOG.Infof(i18n.GetMsgByKey("PullImageSuccess"))
|
||||
err = buserr.WithNameAndErr("ErrDockerPullImage", "", err)
|
||||
return err
|
||||
}
|
||||
t.LogSuccess(i18n.GetMsgByKey("PullImage"))
|
||||
}
|
||||
}
|
||||
|
||||
command := exec.Command("/bin/bash", "-c", fmt.Sprintf("cp -rn %s/* %s || true", detailDir, install.GetPath()))
|
||||
stdout, _ := command.CombinedOutput()
|
||||
if stdout != nil {
|
||||
global.LOG.Infof("upgrade app [%s] [%s] cp file log : %s ", install.App.Key, install.Name, string(stdout))
|
||||
t.Logger.Printf("upgrade app [%s] [%s] cp file log : %s ", install.App.Key, install.Name, string(stdout))
|
||||
}
|
||||
sourceScripts := path.Join(detailDir, "scripts")
|
||||
if fileOp.Stat(sourceScripts) {
|
||||
|
@ -612,9 +586,9 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
|||
|
||||
var newCompose string
|
||||
if req.DockerCompose == "" {
|
||||
newCompose, upErr = getUpgradeCompose(install, detail)
|
||||
if upErr != nil {
|
||||
return
|
||||
newCompose, err = getUpgradeCompose(install, detail)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
newCompose = req.DockerCompose
|
||||
|
@ -627,40 +601,65 @@ func upgradeInstall(req request.AppInstallUpgrade) error {
|
|||
if out, err := compose.Down(install.GetComposePath()); err != nil {
|
||||
if out != "" {
|
||||
upErr = errors.New(out)
|
||||
return
|
||||
return upErr
|
||||
}
|
||||
upErr = err
|
||||
return
|
||||
return err
|
||||
}
|
||||
envs := make(map[string]interface{})
|
||||
if upErr = json.Unmarshal([]byte(install.Env), &envs); upErr != nil {
|
||||
return
|
||||
if err = json.Unmarshal([]byte(install.Env), &envs); err != nil {
|
||||
return err
|
||||
}
|
||||
envParams := make(map[string]string, len(envs))
|
||||
handleMap(envs, envParams)
|
||||
if upErr = env.Write(envParams, install.GetEnvPath()); upErr != nil {
|
||||
return
|
||||
if err = env.Write(envParams, install.GetEnvPath()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//TODO use task
|
||||
if upErr = runScript(nil, &install, "upgrade"); upErr != nil {
|
||||
return
|
||||
if err = runScript(t, &install, "upgrade"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if upErr = fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); upErr != nil {
|
||||
return
|
||||
if err = fileOp.WriteFile(install.GetComposePath(), strings.NewReader(install.DockerCompose), 0775); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logStr := fmt.Sprintf("%s %s", i18n.GetMsgByKey("Run"), i18n.GetMsgByKey("App"))
|
||||
t.Log(logStr)
|
||||
if out, err := compose.Up(install.GetComposePath()); err != nil {
|
||||
if out != "" {
|
||||
upErr = errors.New(out)
|
||||
return errors.New(out)
|
||||
}
|
||||
return err
|
||||
}
|
||||
t.LogSuccess(logStr)
|
||||
install.Status = constant.Running
|
||||
return appInstallRepo.Save(context.Background(), &install)
|
||||
}
|
||||
|
||||
rollBackApp := func(t *task.Task) {
|
||||
if req.Backup {
|
||||
t.Log(i18n.GetWithName("AppRecover", install.Name))
|
||||
if err := NewIBackupService().AppRecover(dto.CommonRecover{Name: install.App.Key, DetailName: install.Name, Type: "app", Source: constant.ResourceLocal, File: backupFile}); err != nil {
|
||||
t.LogFailedWithErr(i18n.GetWithName("AppRecover", install.Name), err)
|
||||
return
|
||||
}
|
||||
upErr = err
|
||||
t.LogSuccess(i18n.GetWithName("AppRecover", install.Name))
|
||||
return
|
||||
}
|
||||
install.Status = constant.Running
|
||||
_ = appInstallRepo.Save(context.Background(), &install)
|
||||
global.LOG.Infof(i18n.GetMsgWithName("UpgradeAppSuccess", install.Name, nil))
|
||||
}
|
||||
|
||||
upgradeTask.AddSubTask(task.GetTaskName(install.Name, task.TaskScopeApp, task.TaskUpgrade), upgradeApp, rollBackApp)
|
||||
|
||||
go func() {
|
||||
err = upgradeTask.Execute()
|
||||
if err != nil {
|
||||
existInstall, _ := appInstallRepo.GetFirst(commonRepo.WithByID(req.InstallID))
|
||||
if existInstall.ID > 0 && existInstall.Status != constant.Running {
|
||||
existInstall.Status = constant.UpgradeErr
|
||||
existInstall.Message = upErr.Error()
|
||||
_ = appInstallRepo.Save(context.Background(), &existInstall)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return appInstallRepo.Save(context.Background(), &install)
|
||||
|
@ -747,9 +746,8 @@ func handleMap(params map[string]interface{}, envParams map[string]string) {
|
|||
}
|
||||
}
|
||||
|
||||
func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.AppInstall) (err error) {
|
||||
func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.AppInstall, logger *log.Logger) (err error) {
|
||||
if app.IsLocalApp() {
|
||||
//本地应用,不去官网下载
|
||||
return nil
|
||||
}
|
||||
appResourceDir := path.Join(constant.AppResourceDir, app.Resource)
|
||||
|
@ -765,7 +763,12 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
|
|||
if !fileOp.Stat(appVersionDir) {
|
||||
_ = fileOp.CreateDir(appVersionDir, 0755)
|
||||
}
|
||||
global.LOG.Infof("download app[%s] from %s", app.Name, appDetail.DownloadUrl)
|
||||
if logger == nil {
|
||||
global.LOG.Infof("download app[%s] from %s", app.Name, appDetail.DownloadUrl)
|
||||
} else {
|
||||
logger.Printf("download app[%s] from %s", app.Name, appDetail.DownloadUrl)
|
||||
}
|
||||
|
||||
filePath := path.Join(appVersionDir, app.Key+"-"+appDetail.Version+".tar.gz")
|
||||
|
||||
defer func() {
|
||||
|
@ -778,11 +781,19 @@ func downloadApp(app model.App, appDetail model.AppDetail, appInstall *model.App
|
|||
}()
|
||||
|
||||
if err = fileOp.DownloadFileWithProxy(appDetail.DownloadUrl, filePath); err != nil {
|
||||
global.LOG.Errorf("download app[%s] error %v", app.Name, err)
|
||||
if logger == nil {
|
||||
global.LOG.Errorf("download app[%s] error %v", app.Name, err)
|
||||
} else {
|
||||
logger.Printf("download app[%s] error %v", app.Name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err = fileOp.Decompress(filePath, appResourceDir, files.SdkTarGz, ""); err != nil {
|
||||
global.LOG.Errorf("decompress app[%s] error %v", app.Name, err)
|
||||
if logger == nil {
|
||||
global.LOG.Errorf("decompress app[%s] error %v", app.Name, err)
|
||||
} else {
|
||||
logger.Printf("decompress app[%s] error %v", app.Name, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
_ = fileOp.DeleteFile(filePath)
|
||||
|
@ -796,7 +807,7 @@ func copyData(task *task.Task, app model.App, appDetail model.AppDetail, appInst
|
|||
appResourceDir := path.Join(constant.AppResourceDir, app.Resource)
|
||||
|
||||
if app.Resource == constant.AppResourceRemote {
|
||||
err = downloadApp(app, appDetail, appInstall)
|
||||
err = downloadApp(app, appDetail, appInstall, task.Logger)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -472,7 +472,7 @@ func (f *FileService) ReadLogByLine(req request.FileReadByLineReq) (*response.Fi
|
|||
if req.TaskID != "" {
|
||||
opts = append(opts, taskRepo.WithByID(req.TaskID))
|
||||
} else {
|
||||
opts = append(opts, taskRepo.WithType(req.TaskType), taskRepo.WithResourceID(req.ID))
|
||||
opts = append(opts, taskRepo.WithType(req.TaskType), taskRepo.WithOperate(req.TaskOperate), taskRepo.WithResourceID(req.ID))
|
||||
}
|
||||
taskModel, err := taskRepo.GetFirst(opts...)
|
||||
if err != nil {
|
||||
|
|
|
@ -114,7 +114,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e
|
|||
|
||||
appVersionDir := filepath.Join(app.GetAppResourcePath(), appDetail.Version)
|
||||
if !fileOp.Stat(appVersionDir) || appDetail.Update {
|
||||
if err = downloadApp(app, appDetail, nil); err != nil {
|
||||
if err = downloadApp(app, appDetail, nil, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error {
|
|||
fileOp := files.NewFileOp()
|
||||
appVersionDir := path.Join(constant.AppResourceDir, app.Resource, app.Key, appDetail.Version)
|
||||
if !fileOp.Stat(appVersionDir) || appDetail.Update {
|
||||
if err := downloadApp(app, appDetail, nil); err != nil {
|
||||
if err := downloadApp(app, appDetail, nil, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = fileOp.Rename(path.Join(runtime.GetPath(), "run.sh"), path.Join(runtime.GetPath(), "run.sh.bak"))
|
||||
|
|
|
@ -347,7 +347,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
|
|||
website.FtpID = itemID
|
||||
return nil
|
||||
}
|
||||
deleteFtpUser := func() {
|
||||
deleteFtpUser := func(t *task.Task) {
|
||||
if website.FtpID > 0 {
|
||||
req := dto.BatchDeleteReq{Ids: []uint{website.FtpID}}
|
||||
if err = NewIFtpService().Delete(req); err != nil {
|
||||
|
@ -381,7 +381,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error)
|
|||
return nil
|
||||
}
|
||||
|
||||
deleteWebsite := func() {
|
||||
deleteWebsite := func(t *task.Task) {
|
||||
_ = deleteWebsiteFolder(nginxInstall, website)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
)
|
||||
|
||||
type ActionFunc func(*Task) error
|
||||
type RollbackFunc func()
|
||||
type RollbackFunc func(*Task)
|
||||
|
||||
type Task struct {
|
||||
Name string
|
||||
|
@ -48,6 +48,7 @@ const (
|
|||
TaskUpgrade = "TaskUpgrade"
|
||||
TaskUpdate = "TaskUpdate"
|
||||
TaskRestart = "TaskRestart"
|
||||
TaskBackup = "TaskBackup"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -67,29 +68,20 @@ func GetTaskName(resourceName, operate, scope string) string {
|
|||
}
|
||||
|
||||
func NewTaskWithOps(resourceName, operate, scope, taskID string, resourceID uint) (*Task, error) {
|
||||
return NewTask(GetTaskName(resourceName, operate, scope), scope, taskID, resourceID)
|
||||
return NewTask(GetTaskName(resourceName, operate, scope), operate, scope, taskID, resourceID)
|
||||
}
|
||||
|
||||
//func NewChildTask(name, taskType, parentTaskID string) (*Task, error) {
|
||||
// task, err := NewTask(name, taskType, "")
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// task.ParentID = parentTaskID
|
||||
// return task, nil
|
||||
//}
|
||||
|
||||
func NewTask(name, taskType, taskID string, resourceID uint) (*Task, error) {
|
||||
func NewTask(name, operate, taskScope, taskID string, resourceID uint) (*Task, error) {
|
||||
if taskID == "" {
|
||||
taskID = uuid.New().String()
|
||||
}
|
||||
logDir := path.Join(constant.LogDir, taskType)
|
||||
logDir := path.Join(constant.LogDir, taskScope)
|
||||
if _, err := os.Stat(logDir); os.IsNotExist(err) {
|
||||
if err = os.MkdirAll(logDir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("failed to create log directory: %w", err)
|
||||
}
|
||||
}
|
||||
logPath := path.Join(constant.LogDir, taskType, taskID+".log")
|
||||
logPath := path.Join(constant.LogDir, taskScope, taskID+".log")
|
||||
file, err := os.OpenFile(logPath, os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0666)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open log file: %w", err)
|
||||
|
@ -98,10 +90,11 @@ func NewTask(name, taskType, taskID string, resourceID uint) (*Task, error) {
|
|||
taskModel := &model.Task{
|
||||
ID: taskID,
|
||||
Name: name,
|
||||
Type: taskType,
|
||||
Type: taskScope,
|
||||
LogFile: logPath,
|
||||
Status: constant.StatusRunning,
|
||||
ResourceID: resourceID,
|
||||
Operate: operate,
|
||||
}
|
||||
taskRepo := repo.NewITaskRepo()
|
||||
task := &Task{Name: name, logFile: file, Logger: logger, taskRepo: taskRepo, Task: taskModel}
|
||||
|
@ -147,7 +140,7 @@ func (s *SubTask) Execute() error {
|
|||
|
||||
if i == s.Retry {
|
||||
if s.Rollback != nil {
|
||||
s.Rollback()
|
||||
s.Rollback(s.RootTask)
|
||||
}
|
||||
}
|
||||
time.Sleep(1 * time.Second)
|
||||
|
@ -176,7 +169,7 @@ func (t *Task) Execute() error {
|
|||
t.Task.ErrorMsg = err.Error()
|
||||
t.Task.Status = constant.StatusFailed
|
||||
for _, rollback := range t.Rollbacks {
|
||||
rollback()
|
||||
rollback(t)
|
||||
}
|
||||
t.updateTask(t.Task)
|
||||
break
|
||||
|
|
|
@ -201,11 +201,11 @@ ErrXpackNotActive: "该部分为专业版功能,请先在 面板设置-许可
|
|||
ErrXpackOutOfDate: "当前许可证已过期,请重新在 面板设置-许可证 界面导入许可证"
|
||||
|
||||
#task
|
||||
TaskStart: "{{.name}} 开始 [START]"
|
||||
TaskEnd: "{{.name}} 结束 [COMPLETED]"
|
||||
TaskFailed: "{{.name}} 失败"
|
||||
TaskStart: "{{.name}} 任务开始 [START]"
|
||||
TaskEnd: "{{.name}} 任务结束 [COMPLETED]"
|
||||
TaskFailed: "{{.name}} 任务失败"
|
||||
TaskTimeout: "{{.name}} 超时"
|
||||
TaskSuccess: "{{.name}} 成功"
|
||||
TaskSuccess: "{{.name}} 任务成功"
|
||||
TaskRetry: "开始第 {{.name}} 次重试"
|
||||
SubTaskSuccess: "{{ .name }} 成功"
|
||||
SubTaskFailed: "{{ .name }} 失败: {{ .err }}"
|
||||
|
@ -216,6 +216,7 @@ TaskDelete: "删除"
|
|||
TaskUpgrade: "升级"
|
||||
TaskUpdate: "更新"
|
||||
TaskRestart: "重启"
|
||||
TaskBackup: "备份"
|
||||
Website: "网站"
|
||||
App: "应用"
|
||||
Runtime: "运行环境"
|
||||
|
@ -232,4 +233,4 @@ HandleDatabaseApp: "处理应用参数"
|
|||
ExecShell: "执行 {{ .name }} 脚本"
|
||||
PullImage: "拉取镜像"
|
||||
Start: "开始"
|
||||
Run: "启动"
|
||||
Run: "启动"
|
||||
|
|
|
@ -276,7 +276,7 @@ var InitPHPExtensions = &gormigrate.Migration{
|
|||
}
|
||||
|
||||
var AddTask = &gormigrate.Migration{
|
||||
ID: "20240801-add-task",
|
||||
ID: "20240802-add-task",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
return tx.AutoMigrate(
|
||||
&model.Task{})
|
||||
|
|
|
@ -53,6 +53,7 @@ const readReq = reactive({
|
|||
pageSize: 500,
|
||||
latest: false,
|
||||
taskType: '',
|
||||
taskOperate: '',
|
||||
id: 0,
|
||||
});
|
||||
|
||||
|
@ -69,9 +70,10 @@ const openWithTaskID = (id: string) => {
|
|||
initData();
|
||||
};
|
||||
|
||||
const openWithResourceID = (taskType: string, resourceID: number) => {
|
||||
const openWithResourceID = (taskType: string, taskOperate: string, resourceID: number) => {
|
||||
readReq.taskType = taskType;
|
||||
readReq.id = resourceID;
|
||||
readReq.taskOperate = taskOperate;
|
||||
initData();
|
||||
};
|
||||
|
||||
|
|
|
@ -270,9 +270,7 @@ const openTaskLog = (taskID: string) => {
|
|||
const install = () => {
|
||||
loading.value = true;
|
||||
const taskID = uuidv4();
|
||||
console.log(taskID);
|
||||
req.taskID = taskID;
|
||||
console.log(req);
|
||||
InstallApp(req)
|
||||
.then(() => {
|
||||
handleClose();
|
||||
|
|
|
@ -116,7 +116,6 @@
|
|||
<el-button link type="info">
|
||||
<span class="name">{{ installed.name }}</span>
|
||||
</el-button>
|
||||
|
||||
<span class="status">
|
||||
<Status
|
||||
:key="installed.status"
|
||||
|
@ -161,6 +160,7 @@
|
|||
</span>
|
||||
<span class="ml-1">
|
||||
<el-tooltip
|
||||
v-if="mode !== 'upgrade'"
|
||||
effect="dark"
|
||||
:content="$t('commons.button.log')"
|
||||
placement="top"
|
||||
|
@ -621,7 +621,7 @@ const quickJump = () => {
|
|||
const openLog = (row: any) => {
|
||||
switch (row.status) {
|
||||
case 'Installing':
|
||||
taskLogRef.value.openWithResourceID('App', row.id);
|
||||
taskLogRef.value.openWithResourceID('App', 'TaskInstall', row.id);
|
||||
break;
|
||||
default:
|
||||
composeLogRef.value.acceptParams({ compose: row.path + '/docker-compose.yml', resource: row.name });
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
</template>
|
||||
<Diff ref="composeDiffRef" @confirm="getNewCompose" />
|
||||
</DrawerPro>
|
||||
<TaskLog ref="taskLogRef" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { App } from '@/api/interface/app';
|
||||
|
@ -88,6 +89,8 @@ import { Rules } from '@/global/form-rules';
|
|||
import Diff from './diff/index.vue';
|
||||
import bus from '../../bus';
|
||||
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
|
||||
import TaskLog from '@/components/task-log/index.vue';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
const composeDiffRef = ref();
|
||||
const updateRef = ref<FormInstance>();
|
||||
|
@ -102,6 +105,7 @@ const operateReq = reactive({
|
|||
pullImage: true,
|
||||
version: '',
|
||||
dockerCompose: '',
|
||||
taskID: '',
|
||||
});
|
||||
const resourceName = ref('');
|
||||
const rules = ref<any>({
|
||||
|
@ -119,6 +123,7 @@ const handleClose = () => {
|
|||
const newCompose = ref('');
|
||||
const useNewCompose = ref(false);
|
||||
const appInstallID = ref(0);
|
||||
const taskLogRef = ref();
|
||||
|
||||
const toLink = (link: string) => {
|
||||
window.open(link, '_blank');
|
||||
|
@ -185,17 +190,24 @@ const getVersions = async (version: string) => {
|
|||
} catch (error) {}
|
||||
};
|
||||
|
||||
const openTaskLog = (taskID: string) => {
|
||||
taskLogRef.value.openWithTaskID(taskID);
|
||||
};
|
||||
|
||||
const operate = async () => {
|
||||
loading.value = true;
|
||||
if (operateReq.operate === 'upgrade') {
|
||||
if (useNewCompose.value) {
|
||||
operateReq.dockerCompose = newCompose.value;
|
||||
}
|
||||
const taskID = uuidv4();
|
||||
operateReq.taskID = taskID;
|
||||
await InstalledOp(operateReq)
|
||||
.then(() => {
|
||||
MsgSuccess(i18n.global.t('app.upgradeStart'));
|
||||
bus.emit('upgrade', true);
|
||||
handleClose();
|
||||
openTaskLog(taskID);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue