mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-01 03:24:14 +08:00
parent
f3fd02fcb3
commit
86bf7ea73a
@ -86,6 +86,21 @@ func (b *BaseApi) UpdateDeviceByFile(c *gin.Context) {
|
|||||||
helper.SuccessWithData(c, nil)
|
helper.SuccessWithData(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags Device
|
||||||
|
// @Summary Load user list
|
||||||
|
// @Description 获取服务器用户列表
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /toolbox/device/users [get]
|
||||||
|
func (b *BaseApi) LoadUsers(c *gin.Context) {
|
||||||
|
users, err := deviceService.LoadUsers()
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
helper.SuccessWithData(c, users)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags Device
|
// @Tags Device
|
||||||
// @Summary Update device
|
// @Summary Update device
|
||||||
// @Description 修改系统参数
|
// @Description 修改系统参数
|
||||||
|
@ -21,9 +21,13 @@ type CronjobCreate struct {
|
|||||||
SpecCustom bool `json:"specCustom"`
|
SpecCustom bool `json:"specCustom"`
|
||||||
Spec string `json:"spec" validate:"required"`
|
Spec string `json:"spec" validate:"required"`
|
||||||
|
|
||||||
Script string `json:"script"`
|
Executor string `json:"executor"`
|
||||||
Command string `json:"command"`
|
ScriptMode string `json:"scriptMode"`
|
||||||
ContainerName string `json:"containerName"`
|
Script string `json:"script"`
|
||||||
|
Command string `json:"command"`
|
||||||
|
ContainerName string `json:"containerName"`
|
||||||
|
User string `json:"user"`
|
||||||
|
|
||||||
AppID string `json:"appID"`
|
AppID string `json:"appID"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
ExclusionRules string `json:"exclusionRules"`
|
ExclusionRules string `json:"exclusionRules"`
|
||||||
@ -44,9 +48,13 @@ type CronjobUpdate struct {
|
|||||||
SpecCustom bool `json:"specCustom"`
|
SpecCustom bool `json:"specCustom"`
|
||||||
Spec string `json:"spec" validate:"required"`
|
Spec string `json:"spec" validate:"required"`
|
||||||
|
|
||||||
Script string `json:"script"`
|
Executor string `json:"executor"`
|
||||||
Command string `json:"command"`
|
ScriptMode string `json:"scriptMode"`
|
||||||
ContainerName string `json:"containerName"`
|
Script string `json:"script"`
|
||||||
|
Command string `json:"command"`
|
||||||
|
ContainerName string `json:"containerName"`
|
||||||
|
User string `json:"user"`
|
||||||
|
|
||||||
AppID string `json:"appID"`
|
AppID string `json:"appID"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
ExclusionRules string `json:"exclusionRules"`
|
ExclusionRules string `json:"exclusionRules"`
|
||||||
@ -89,9 +97,13 @@ type CronjobInfo struct {
|
|||||||
SpecCustom bool `json:"specCustom"`
|
SpecCustom bool `json:"specCustom"`
|
||||||
Spec string `json:"spec"`
|
Spec string `json:"spec"`
|
||||||
|
|
||||||
Script string `json:"script"`
|
Executor string `json:"executor"`
|
||||||
Command string `json:"command"`
|
ScriptMode string `json:"scriptMode"`
|
||||||
ContainerName string `json:"containerName"`
|
Script string `json:"script"`
|
||||||
|
Command string `json:"command"`
|
||||||
|
ContainerName string `json:"containerName"`
|
||||||
|
User string `json:"user"`
|
||||||
|
|
||||||
AppID string `json:"appID"`
|
AppID string `json:"appID"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
ExclusionRules string `json:"exclusionRules"`
|
ExclusionRules string `json:"exclusionRules"`
|
||||||
|
@ -14,9 +14,13 @@ type Cronjob struct {
|
|||||||
SpecCustom bool `json:"specCustom"`
|
SpecCustom bool `json:"specCustom"`
|
||||||
Spec string `gorm:"not null" json:"spec"`
|
Spec string `gorm:"not null" json:"spec"`
|
||||||
|
|
||||||
Command string `json:"command"`
|
Executor string `json:"executor"`
|
||||||
ContainerName string `json:"containerName"`
|
Command string `json:"command"`
|
||||||
Script string `json:"script"`
|
ContainerName string `json:"containerName"`
|
||||||
|
ScriptMode string `json:"scriptMode"`
|
||||||
|
Script string `json:"script"`
|
||||||
|
User string `json:"user"`
|
||||||
|
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
AppID string `json:"appID"`
|
AppID string `json:"appID"`
|
||||||
DBType string `json:"dbType"`
|
DBType string `json:"dbType"`
|
||||||
@ -39,6 +43,7 @@ type JobRecords struct {
|
|||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
CronjobID uint `json:"cronjobID"`
|
CronjobID uint `json:"cronjobID"`
|
||||||
|
TaskID string `json:"taskID"`
|
||||||
StartTime time.Time `json:"startTime"`
|
StartTime time.Time `json:"startTime"`
|
||||||
Interval float64 `json:"interval"`
|
Interval float64 `json:"interval"`
|
||||||
Records string `json:"records"`
|
Records string `json:"records"`
|
||||||
|
@ -182,13 +182,13 @@ func (u *CronjobService) HandleOnce(id uint) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *CronjobService) Create(cronjobDto dto.CronjobCreate) error {
|
func (u *CronjobService) Create(req dto.CronjobCreate) error {
|
||||||
cronjob, _ := cronjobRepo.Get(commonRepo.WithByName(cronjobDto.Name))
|
cronjob, _ := cronjobRepo.Get(commonRepo.WithByName(req.Name))
|
||||||
if cronjob.ID != 0 {
|
if cronjob.ID != 0 {
|
||||||
return constant.ErrRecordExist
|
return constant.ErrRecordExist
|
||||||
}
|
}
|
||||||
cronjob.Secret = cronjobDto.Secret
|
cronjob.Secret = req.Secret
|
||||||
if err := copier.Copy(&cronjob, &cronjobDto); err != nil {
|
if err := copier.Copy(&cronjob, &req); err != nil {
|
||||||
return errors.WithMessage(constant.ErrStructTransform, err.Error())
|
return errors.WithMessage(constant.ErrStructTransform, err.Error())
|
||||||
}
|
}
|
||||||
cronjob.Status = constant.StatusEnable
|
cronjob.Status = constant.StatusEnable
|
||||||
@ -282,8 +282,11 @@ func (u *CronjobService) Update(id uint, req dto.CronjobUpdate) error {
|
|||||||
upMap["spec_custom"] = req.SpecCustom
|
upMap["spec_custom"] = req.SpecCustom
|
||||||
upMap["spec"] = spec
|
upMap["spec"] = spec
|
||||||
upMap["script"] = req.Script
|
upMap["script"] = req.Script
|
||||||
|
upMap["script_mode"] = req.ScriptMode
|
||||||
upMap["command"] = req.Command
|
upMap["command"] = req.Command
|
||||||
upMap["container_name"] = req.ContainerName
|
upMap["container_name"] = req.ContainerName
|
||||||
|
upMap["executor"] = req.Executor
|
||||||
|
upMap["user"] = req.User
|
||||||
upMap["app_id"] = req.AppID
|
upMap["app_id"] = req.AppID
|
||||||
upMap["website"] = req.Website
|
upMap["website"] = req.Website
|
||||||
upMap["exclusion_rules"] = req.ExclusionRules
|
upMap["exclusion_rules"] = req.ExclusionRules
|
||||||
|
@ -8,13 +8,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/buserr"
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/i18n"
|
|
||||||
|
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/model"
|
"github.com/1Panel-dev/1Panel/agent/app/model"
|
||||||
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
"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/constant"
|
||||||
"github.com/1Panel-dev/1Panel/agent/global"
|
"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/cmd"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
"github.com/1Panel-dev/1Panel/agent/utils/files"
|
||||||
"github.com/1Panel-dev/1Panel/agent/utils/ntp"
|
"github.com/1Panel-dev/1Panel/agent/utils/ntp"
|
||||||
@ -35,15 +34,7 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
|||||||
}
|
}
|
||||||
record.Records = u.generateLogsPath(*cronjob, record.StartTime)
|
record.Records = u.generateLogsPath(*cronjob, record.StartTime)
|
||||||
_ = cronjobRepo.UpdateRecords(record.ID, map[string]interface{}{"records": record.Records})
|
_ = cronjobRepo.UpdateRecords(record.ID, map[string]interface{}{"records": record.Records})
|
||||||
script := cronjob.Script
|
err = u.handleShell(*cronjob, record.Records)
|
||||||
if len(cronjob.ContainerName) != 0 {
|
|
||||||
command := "sh"
|
|
||||||
if len(cronjob.Command) != 0 {
|
|
||||||
command = cronjob.Command
|
|
||||||
}
|
|
||||||
script = fmt.Sprintf("docker exec %s %s -c \"%s\"", cronjob.ContainerName, command, strings.ReplaceAll(cronjob.Script, "\"", "\\\""))
|
|
||||||
}
|
|
||||||
err = u.handleShell(cronjob.Type, cronjob.Name, script, record.Records)
|
|
||||||
u.removeExpiredLog(*cronjob)
|
u.removeExpiredLog(*cronjob)
|
||||||
case "curl":
|
case "curl":
|
||||||
if len(cronjob.URL) == 0 {
|
if len(cronjob.URL) == 0 {
|
||||||
@ -51,7 +42,7 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
|||||||
}
|
}
|
||||||
record.Records = u.generateLogsPath(*cronjob, record.StartTime)
|
record.Records = u.generateLogsPath(*cronjob, record.StartTime)
|
||||||
_ = cronjobRepo.UpdateRecords(record.ID, map[string]interface{}{"records": record.Records})
|
_ = cronjobRepo.UpdateRecords(record.ID, map[string]interface{}{"records": record.Records})
|
||||||
err = u.handleShell(cronjob.Type, cronjob.Name, fmt.Sprintf("curl '%s'", cronjob.URL), record.Records)
|
err = cmd.ExecShell(record.Records, 24*time.Hour, "bash", "-c", "curl", cronjob.URL)
|
||||||
u.removeExpiredLog(*cronjob)
|
u.removeExpiredLog(*cronjob)
|
||||||
case "ntp":
|
case "ntp":
|
||||||
err = u.handleNtpSync()
|
err = u.handleNtpSync()
|
||||||
@ -100,17 +91,29 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *CronjobService) handleShell(cronType, cornName, script, logPath string) error {
|
func (u *CronjobService) handleShell(cronjob model.Cronjob, logPath string) error {
|
||||||
handleDir := fmt.Sprintf("%s/task/%s/%s", constant.DataDir, cronType, cornName)
|
if len(cronjob.ContainerName) != 0 {
|
||||||
if _, err := os.Stat(handleDir); err != nil && os.IsNotExist(err) {
|
command := "sh"
|
||||||
if err = os.MkdirAll(handleDir, os.ModePerm); err != nil {
|
if len(cronjob.Command) != 0 {
|
||||||
|
command = cronjob.Command
|
||||||
|
}
|
||||||
|
scriptFile, _ := os.ReadFile(cronjob.Script)
|
||||||
|
return cmd.ExecShell(logPath, 24*time.Hour, "docker", "exec", cronjob.ContainerName, command, "-c", strings.ReplaceAll(string(scriptFile), "\"", "\\\""))
|
||||||
|
}
|
||||||
|
if cronjob.ScriptMode == "input" {
|
||||||
|
fileItem := path.Join(global.CONF.System.BaseDir, "1panel", "task", "shell", cronjob.Name, cronjob.Name+".sh")
|
||||||
|
_ = os.MkdirAll(path.Dir(fileItem), os.ModePerm)
|
||||||
|
shellFile, err := os.OpenFile(fileItem, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer shellFile.Close()
|
||||||
|
if _, err := shellFile.WriteString(cronjob.Script); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cmd.ExecShell(logPath, 24*time.Hour, "sudo", "-u", cronjob.User, cronjob.Executor, fileItem)
|
||||||
}
|
}
|
||||||
if err := cmd.ExecCronjobWithTimeOut(script, handleDir, logPath, 24*time.Hour); err != nil {
|
return cmd.ExecShell(logPath, 24*time.Hour, "sudo", "-u", cronjob.User, cronjob.Executor, cronjob.Script)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *CronjobService) handleNtpSync() error {
|
func (u *CronjobService) handleNtpSync() error {
|
||||||
|
@ -37,6 +37,7 @@ type IDeviceService interface {
|
|||||||
LoadTimeZone() ([]string, error)
|
LoadTimeZone() ([]string, error)
|
||||||
CheckDNS(key, value string) (bool, error)
|
CheckDNS(key, value string) (bool, error)
|
||||||
LoadConf(name string) (string, error)
|
LoadConf(name string) (string, error)
|
||||||
|
LoadUsers() ([]string, error)
|
||||||
|
|
||||||
Scan() dto.CleanData
|
Scan() dto.CleanData
|
||||||
Clean(req []dto.Clean)
|
Clean(req []dto.Clean)
|
||||||
@ -168,6 +169,21 @@ func (u *DeviceService) Update(key, value string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *DeviceService) LoadUsers() ([]string, error) {
|
||||||
|
file, err := os.ReadFile("/etc/passwd")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var users []string
|
||||||
|
lines := strings.Split(string(file), "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.Contains(line, ":") {
|
||||||
|
users = append(users, strings.Split(line, ":")[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (u *DeviceService) UpdateHosts(req []dto.HostHelper) error {
|
func (u *DeviceService) UpdateHosts(req []dto.HostHelper) error {
|
||||||
conf, err := os.ReadFile(defaultHostPath)
|
conf, err := os.ReadFile(defaultHostPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -58,6 +58,7 @@ const (
|
|||||||
TaskBuild = "TaskBuild"
|
TaskBuild = "TaskBuild"
|
||||||
TaskPull = "TaskPull"
|
TaskPull = "TaskPull"
|
||||||
TaskPush = "TaskPush"
|
TaskPush = "TaskPush"
|
||||||
|
TaskHandle = "TaskHandle"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -65,6 +66,7 @@ const (
|
|||||||
TaskScopeApp = "App"
|
TaskScopeApp = "App"
|
||||||
TaskScopeRuntime = "Runtime"
|
TaskScopeRuntime = "Runtime"
|
||||||
TaskScopeDatabase = "Database"
|
TaskScopeDatabase = "Database"
|
||||||
|
TaskScopeCronjob = "Cronjob"
|
||||||
TaskScopeAppStore = "AppStore"
|
TaskScopeAppStore = "AppStore"
|
||||||
TaskScopeSnapshot = "Snapshot"
|
TaskScopeSnapshot = "Snapshot"
|
||||||
TaskScopeContainer = "Container"
|
TaskScopeContainer = "Container"
|
||||||
|
@ -227,6 +227,7 @@ TaskRollback: "Rollback"
|
|||||||
TaskPull: "Pull"
|
TaskPull: "Pull"
|
||||||
TaskBuild: "Build"
|
TaskBuild: "Build"
|
||||||
TaskPush: "Push"
|
TaskPush: "Push"
|
||||||
|
TaskHandle: "Execute"
|
||||||
Website: "Website"
|
Website: "Website"
|
||||||
App: "App"
|
App: "App"
|
||||||
Runtime: "Runtime"
|
Runtime: "Runtime"
|
||||||
|
@ -229,6 +229,7 @@ TaskRollback: "回滚"
|
|||||||
TaskPull: "拉取"
|
TaskPull: "拉取"
|
||||||
TaskBuild: "建構"
|
TaskBuild: "建構"
|
||||||
TaskPush: "推送"
|
TaskPush: "推送"
|
||||||
|
TaskHandle: "執行"
|
||||||
Website: "網站"
|
Website: "網站"
|
||||||
App: "應用"
|
App: "應用"
|
||||||
Runtime: "運行環境"
|
Runtime: "運行環境"
|
||||||
|
@ -231,6 +231,7 @@ TaskRollback: "回滚"
|
|||||||
TaskPull: "拉取"
|
TaskPull: "拉取"
|
||||||
TaskBuild: "构建"
|
TaskBuild: "构建"
|
||||||
TaskPush: "推送"
|
TaskPush: "推送"
|
||||||
|
TaskHandle: "执行"
|
||||||
Website: "网站"
|
Website: "网站"
|
||||||
App: "应用"
|
App: "应用"
|
||||||
Runtime: "运行环境"
|
Runtime: "运行环境"
|
||||||
|
@ -22,6 +22,7 @@ func Init() {
|
|||||||
migrations.AddTaskDB,
|
migrations.AddTaskDB,
|
||||||
migrations.UpdateAppInstall,
|
migrations.UpdateAppInstall,
|
||||||
migrations.UpdateSnapshot,
|
migrations.UpdateSnapshot,
|
||||||
|
migrations.UpdateCronjob,
|
||||||
})
|
})
|
||||||
if err := m.Migrate(); err != nil {
|
if err := m.Migrate(); err != nil {
|
||||||
global.LOG.Error(err)
|
global.LOG.Error(err)
|
||||||
|
@ -266,3 +266,10 @@ var UpdateSnapshot = &gormigrate.Migration{
|
|||||||
return tx.AutoMigrate(&model.Snapshot{})
|
return tx.AutoMigrate(&model.Snapshot{})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var UpdateCronjob = &gormigrate.Migration{
|
||||||
|
ID: "20241011-update-cronjob",
|
||||||
|
Migrate: func(tx *gorm.DB) error {
|
||||||
|
return tx.AutoMigrate(&model.Cronjob{}, &model.JobRecords{})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ func (s *ToolboxRouter) InitRouter(Router *gin.RouterGroup) {
|
|||||||
baseApi := v2.ApiGroupApp.BaseApi
|
baseApi := v2.ApiGroupApp.BaseApi
|
||||||
{
|
{
|
||||||
toolboxRouter.POST("/device/base", baseApi.LoadDeviceBaseInfo)
|
toolboxRouter.POST("/device/base", baseApi.LoadDeviceBaseInfo)
|
||||||
|
toolboxRouter.GET("/device/users", baseApi.LoadUsers)
|
||||||
toolboxRouter.GET("/device/zone/options", baseApi.LoadTimeOption)
|
toolboxRouter.GET("/device/zone/options", baseApi.LoadTimeOption)
|
||||||
toolboxRouter.POST("/device/update/conf", baseApi.UpdateDeviceConf)
|
toolboxRouter.POST("/device/update/conf", baseApi.UpdateDeviceConf)
|
||||||
toolboxRouter.POST("/device/update/host", baseApi.UpdateDeviceHost)
|
toolboxRouter.POST("/device/update/host", baseApi.UpdateDeviceHost)
|
||||||
|
@ -107,15 +107,14 @@ func ExecContainerScript(containerName, cmdStr string, timeout time.Duration) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExecCronjobWithTimeOut(cmdStr, workdir, outPath string, timeout time.Duration) error {
|
func ExecShell(outPath string, timeout time.Duration, name string, arg ...string) error {
|
||||||
file, err := os.OpenFile(outPath, os.O_WRONLY|os.O_CREATE, 0666)
|
file, err := os.OpenFile(outPath, os.O_WRONLY|os.O_CREATE, 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
cmd := exec.Command("bash", "-c", cmdStr)
|
cmd := exec.Command(name, arg...)
|
||||||
cmd.Dir = workdir
|
|
||||||
cmd.Stdout = file
|
cmd.Stdout = file
|
||||||
cmd.Stderr = file
|
cmd.Stderr = file
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
@ -10,11 +10,15 @@ export namespace Cronjob {
|
|||||||
specs: Array<string>;
|
specs: Array<string>;
|
||||||
specObjs: Array<SpecObj>;
|
specObjs: Array<SpecObj>;
|
||||||
|
|
||||||
|
executor: string;
|
||||||
|
isExecutorCustom: boolean;
|
||||||
script: string;
|
script: string;
|
||||||
|
scriptMode: string;
|
||||||
isCustom: boolean;
|
isCustom: boolean;
|
||||||
command: string;
|
command: string;
|
||||||
inContainer: boolean;
|
inContainer: boolean;
|
||||||
containerName: string;
|
containerName: string;
|
||||||
|
user: string;
|
||||||
appID: string;
|
appID: string;
|
||||||
website: string;
|
website: string;
|
||||||
exclusionRules: string;
|
exclusionRules: string;
|
||||||
|
@ -12,6 +12,9 @@ export const getDeviceBase = () => {
|
|||||||
export const loadTimeZoneOptions = () => {
|
export const loadTimeZoneOptions = () => {
|
||||||
return http.get<Array<string>>(`/toolbox/device/zone/options`);
|
return http.get<Array<string>>(`/toolbox/device/zone/options`);
|
||||||
};
|
};
|
||||||
|
export const loadUsers = () => {
|
||||||
|
return http.get<Array<string>>(`/toolbox/device/users`);
|
||||||
|
};
|
||||||
export const updateDevice = (key: string, value: string) => {
|
export const updateDevice = (key: string, value: string) => {
|
||||||
return http.post(`/toolbox/device/update/conf`, { key: key, value: value }, TimeoutEnum.T_60S);
|
return http.post(`/toolbox/device/update/conf`, { key: key, value: value }, TimeoutEnum.T_60S);
|
||||||
};
|
};
|
||||||
|
@ -13,6 +13,7 @@ import { oneDark } from '@codemirror/theme-one-dark';
|
|||||||
import { StreamLanguage } from '@codemirror/language';
|
import { StreamLanguage } from '@codemirror/language';
|
||||||
import { nginx } from './nginx';
|
import { nginx } from './nginx';
|
||||||
import { yaml } from '@codemirror/legacy-modes/mode/yaml';
|
import { yaml } from '@codemirror/legacy-modes/mode/yaml';
|
||||||
|
import { shell } from '@codemirror/legacy-modes/mode/shell';
|
||||||
import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile';
|
import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile';
|
||||||
import { placeholder } from '@codemirror/view';
|
import { placeholder } from '@codemirror/view';
|
||||||
import { json } from '@codemirror/lang-json';
|
import { json } from '@codemirror/lang-json';
|
||||||
@ -93,6 +94,9 @@ const initCodeMirror = () => {
|
|||||||
case 'json':
|
case 'json':
|
||||||
extensions.push(json());
|
extensions.push(json());
|
||||||
break;
|
break;
|
||||||
|
case 'shell':
|
||||||
|
extensions.push(StreamLanguage.define(shell));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
let startState = EditorState.create({
|
let startState = EditorState.create({
|
||||||
doc: content.value,
|
doc: content.value,
|
||||||
|
@ -923,6 +923,7 @@ const message = {
|
|||||||
saturday: 'Saturday',
|
saturday: 'Saturday',
|
||||||
sunday: 'Sunday',
|
sunday: 'Sunday',
|
||||||
shellContent: 'Script',
|
shellContent: 'Script',
|
||||||
|
executor: 'Executor',
|
||||||
errRecord: 'Incorrect logging',
|
errRecord: 'Incorrect logging',
|
||||||
errHandle: 'Cronjob execution failure',
|
errHandle: 'Cronjob execution failure',
|
||||||
noRecord: 'The execution did not generate any logs',
|
noRecord: 'The execution did not generate any logs',
|
||||||
|
@ -878,6 +878,7 @@ const message = {
|
|||||||
saturday: '周六',
|
saturday: '周六',
|
||||||
sunday: '周日',
|
sunday: '周日',
|
||||||
shellContent: '腳本內容',
|
shellContent: '腳本內容',
|
||||||
|
executor: '解釋器',
|
||||||
errRecord: '錯誤的日誌記錄',
|
errRecord: '錯誤的日誌記錄',
|
||||||
errHandle: '任務執行失敗',
|
errHandle: '任務執行失敗',
|
||||||
noRecord: '當前計劃任務暫未產生記錄',
|
noRecord: '當前計劃任務暫未產生記錄',
|
||||||
|
@ -879,6 +879,7 @@ const message = {
|
|||||||
saturday: '周六',
|
saturday: '周六',
|
||||||
sunday: '周日',
|
sunday: '周日',
|
||||||
shellContent: '脚本内容',
|
shellContent: '脚本内容',
|
||||||
|
executor: '解释器',
|
||||||
errRecord: '错误的日志记录',
|
errRecord: '错误的日志记录',
|
||||||
errHandle: '任务执行失败',
|
errHandle: '任务执行失败',
|
||||||
noRecord: '当前计划任务暂未产生记录',
|
noRecord: '当前计划任务暂未产生记录',
|
||||||
|
@ -67,149 +67,251 @@
|
|||||||
<el-form-item :label="$t('cronjob.taskName')" prop="name">
|
<el-form-item :label="$t('cronjob.taskName')" prop="name">
|
||||||
<el-input :disabled="dialogData.title === 'edit'" clearable v-model.trim="dialogData.rowData!.name" />
|
<el-input :disabled="dialogData.title === 'edit'" clearable v-model.trim="dialogData.rowData!.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-card>
|
||||||
<el-form-item :label="$t('cronjob.cronSpec')" prop="specCustom">
|
<el-form-item :label="$t('cronjob.cronSpec')" prop="specCustom">
|
||||||
<el-checkbox :label="$t('container.custom')" v-model="dialogData.rowData!.specCustom" />
|
<el-checkbox :label="$t('container.custom')" v-model="dialogData.rowData!.specCustom" />
|
||||||
</el-form-item>
|
|
||||||
<div v-if="!dialogData.rowData!.specCustom">
|
|
||||||
<el-form-item prop="spec">
|
|
||||||
<div v-for="(specObj, index) of dialogData.rowData.specObjs" :key="index" style="width: 100%">
|
|
||||||
<el-select class="specTypeClass" v-model="specObj.specType" @change="changeSpecType(index)">
|
|
||||||
<el-option
|
|
||||||
v-for="item in specOptions"
|
|
||||||
:key="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
<el-select v-if="specObj.specType === 'perWeek'" class="specClass" v-model="specObj.week">
|
|
||||||
<el-option
|
|
||||||
v-for="item in weekOptions"
|
|
||||||
:key="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
<el-input v-if="hasDay(specObj)" class="specClass" v-model.number="specObj.day">
|
|
||||||
<template #append>
|
|
||||||
<div class="append">{{ $t('cronjob.day') }}</div>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<el-input v-if="hasHour(specObj)" class="specClass" v-model.number="specObj.hour">
|
|
||||||
<template #append>
|
|
||||||
<div class="append">{{ $t('commons.units.hour') }}</div>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<el-input
|
|
||||||
v-if="specObj.specType !== 'perNSecond'"
|
|
||||||
class="specClass"
|
|
||||||
v-model.number="specObj.minute"
|
|
||||||
>
|
|
||||||
<template #append>
|
|
||||||
<div class="append">{{ $t('commons.units.minute') }}</div>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<el-input
|
|
||||||
v-if="specObj.specType === 'perNSecond'"
|
|
||||||
class="specClass"
|
|
||||||
v-model.number="specObj.second"
|
|
||||||
>
|
|
||||||
<template #append>
|
|
||||||
<div class="append">{{ $t('commons.units.second') }}</div>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<el-popover placement="top-start" :title="$t('cronjob.nextTime')" width="200" trigger="click">
|
|
||||||
<div v-for="(time, index_t) of nextTimes" :key="index_t">
|
|
||||||
<el-tag class="mt-2">{{ time }}</el-tag>
|
|
||||||
</div>
|
|
||||||
<template #reference>
|
|
||||||
<el-button class="ml-2.5" @click="loadNext(specObj)" link type="primary">
|
|
||||||
{{ $t('commons.button.preview') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-popover>
|
|
||||||
<el-button
|
|
||||||
class="ml-2.5"
|
|
||||||
link
|
|
||||||
type="primary"
|
|
||||||
@click="handleSpecDelete(index)"
|
|
||||||
v-if="dialogData.rowData.specObjs.length > 1"
|
|
||||||
>
|
|
||||||
{{ $t('commons.button.delete') }}
|
|
||||||
</el-button>
|
|
||||||
<el-divider v-if="dialogData.rowData.specObjs.length > 1" class="divider" />
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-button class="mb-3" @click="handleSpecAdd()">
|
<div v-if="!dialogData.rowData!.specCustom">
|
||||||
{{ $t('commons.button.add') }}
|
<el-form-item prop="spec">
|
||||||
</el-button>
|
<div v-for="(specObj, index) of dialogData.rowData.specObjs" :key="index" style="width: 100%">
|
||||||
</div>
|
<el-select class="specTypeClass" v-model="specObj.specType" @change="changeSpecType(index)">
|
||||||
|
<el-option
|
||||||
|
v-for="item in specOptions"
|
||||||
|
:key="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<el-select v-if="specObj.specType === 'perWeek'" class="specClass" v-model="specObj.week">
|
||||||
|
<el-option
|
||||||
|
v-for="item in weekOptions"
|
||||||
|
:key="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<el-input v-if="hasDay(specObj)" class="specClass" v-model.number="specObj.day">
|
||||||
|
<template #append>
|
||||||
|
<div class="append">{{ $t('cronjob.day') }}</div>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<el-input v-if="hasHour(specObj)" class="specClass" v-model.number="specObj.hour">
|
||||||
|
<template #append>
|
||||||
|
<div class="append">{{ $t('commons.units.hour') }}</div>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<el-input
|
||||||
|
v-if="specObj.specType !== 'perNSecond'"
|
||||||
|
class="specClass"
|
||||||
|
v-model.number="specObj.minute"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<div class="append">{{ $t('commons.units.minute') }}</div>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<el-input
|
||||||
|
v-if="specObj.specType === 'perNSecond'"
|
||||||
|
class="specClass"
|
||||||
|
v-model.number="specObj.second"
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<div class="append">{{ $t('commons.units.second') }}</div>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
<el-popover
|
||||||
|
placement="top-start"
|
||||||
|
:title="$t('cronjob.nextTime')"
|
||||||
|
width="200"
|
||||||
|
trigger="click"
|
||||||
|
>
|
||||||
|
<div v-for="(time, index_t) of nextTimes" :key="index_t">
|
||||||
|
<el-tag class="mt-2">{{ time }}</el-tag>
|
||||||
|
</div>
|
||||||
|
<template #reference>
|
||||||
|
<el-button class="ml-2.5" @click="loadNext(specObj)" link type="primary">
|
||||||
|
{{ $t('commons.button.preview') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
<el-button
|
||||||
|
class="ml-2.5"
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="handleSpecDelete(index)"
|
||||||
|
v-if="dialogData.rowData.specObjs.length > 1"
|
||||||
|
>
|
||||||
|
{{ $t('commons.button.delete') }}
|
||||||
|
</el-button>
|
||||||
|
<el-divider v-if="dialogData.rowData.specObjs.length > 1" class="divider" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-button class="mb-3" @click="handleSpecAdd()">
|
||||||
|
{{ $t('commons.button.add') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="dialogData.rowData!.specCustom">
|
<div v-if="dialogData.rowData!.specCustom">
|
||||||
<el-form-item prop="spec">
|
<el-form-item prop="spec">
|
||||||
<div v-for="(spec, index) of dialogData.rowData.specs" :key="index" style="width: 100%">
|
<div v-for="(spec, index) of dialogData.rowData.specs" :key="index">
|
||||||
<el-input style="width: 80%" v-model="dialogData.rowData.specs[index]" />
|
<el-input style="width: 80%" v-model="dialogData.rowData.specs[index]" />
|
||||||
<el-popover placement="top-start" :title="$t('cronjob.nextTime')" width="200" trigger="click">
|
<el-popover
|
||||||
<div v-for="(time, index_t) of nextTimes" :key="index_t">
|
placement="top-start"
|
||||||
<el-tag class="mt-2">{{ time }}</el-tag>
|
:title="$t('cronjob.nextTime')"
|
||||||
</div>
|
width="200"
|
||||||
<template #reference>
|
trigger="click"
|
||||||
<el-button class="ml-2.5" @click="loadNext(spec)" link type="primary">
|
>
|
||||||
{{ $t('commons.button.preview') }}
|
<div v-for="(time, index_t) of nextTimes" :key="index_t">
|
||||||
</el-button>
|
<el-tag class="mt-2">{{ time }}</el-tag>
|
||||||
</template>
|
</div>
|
||||||
</el-popover>
|
<template #reference>
|
||||||
<el-button
|
<el-button class="ml-2.5" @click="loadNext(spec)" link type="primary">
|
||||||
class="ml-2.5"
|
{{ $t('commons.button.preview') }}
|
||||||
link
|
</el-button>
|
||||||
type="primary"
|
</template>
|
||||||
@click="handleSpecCustomDelete(index)"
|
</el-popover>
|
||||||
v-if="dialogData.rowData.specs.length > 1"
|
<el-button
|
||||||
>
|
class="ml-2.5"
|
||||||
{{ $t('commons.button.delete') }}
|
link
|
||||||
</el-button>
|
type="primary"
|
||||||
<el-divider v-if="dialogData.rowData.specs.length > 1" class="divider" />
|
@click="handleSpecCustomDelete(index)"
|
||||||
</div>
|
v-if="dialogData.rowData.specs.length > 1"
|
||||||
|
>
|
||||||
|
{{ $t('commons.button.delete') }}
|
||||||
|
</el-button>
|
||||||
|
<el-divider v-if="dialogData.rowData.specs.length > 1" class="divider" />
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<el-button class="mb-3" @click="handleSpecCustomAdd()">
|
||||||
|
{{ $t('commons.button.add') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<div v-if="hasScript()">
|
||||||
|
<el-form-item class="mt-5">
|
||||||
|
<el-checkbox v-model="dialogData.rowData!.inContainer">
|
||||||
|
{{ $t('cronjob.containerCheckBox') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
<el-card v-if="dialogData.rowData!.inContainer">
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('cronjob.containerName')" prop="containerName">
|
||||||
|
<el-select class="selectClass" v-model="dialogData.rowData!.containerName">
|
||||||
|
<el-option
|
||||||
|
v-for="item in containerOptions"
|
||||||
|
:key="item"
|
||||||
|
:value="item"
|
||||||
|
:label="item"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item :label="$t('container.command')" prop="command" :rules="Rules.requiredInput">
|
||||||
|
<el-checkbox border v-model="dialogData.rowData!.isCustom">
|
||||||
|
{{ $t('container.custom') }}
|
||||||
|
</el-checkbox>
|
||||||
|
<el-select
|
||||||
|
v-if="!dialogData.rowData!.isCustom"
|
||||||
|
style="width: calc(100% - 100px)"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
v-model="dialogData.rowData!.command"
|
||||||
|
>
|
||||||
|
<el-option value="ash" label="/bin/ash" />
|
||||||
|
<el-option value="bash" label="/bin/bash" />
|
||||||
|
<el-option value="sh" label="/bin/sh" />
|
||||||
|
</el-select>
|
||||||
|
<el-input
|
||||||
|
clearable
|
||||||
|
v-else
|
||||||
|
style="width: calc(100% - 100px)"
|
||||||
|
v-model="dialogData.rowData!.command"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
<div v-if="!dialogData.rowData!.inContainer">
|
||||||
|
<el-card>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('commons.table.user')"
|
||||||
|
prop="user"
|
||||||
|
:rules="Rules.requiredSelect"
|
||||||
|
>
|
||||||
|
<el-select filterable v-model="dialogData.rowData!.user">
|
||||||
|
<div v-for="item in userOptions" :key="item">
|
||||||
|
<el-option :value="item" :label="item" />
|
||||||
|
</div>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item
|
||||||
|
:label="$t('cronjob.executor')"
|
||||||
|
prop="executor"
|
||||||
|
:rules="Rules.requiredSelect"
|
||||||
|
>
|
||||||
|
<el-checkbox border v-model="dialogData.rowData!.isExecutorCustom">
|
||||||
|
{{ $t('container.custom') }}
|
||||||
|
</el-checkbox>
|
||||||
|
<el-select
|
||||||
|
v-if="!dialogData.rowData!.isExecutorCustom"
|
||||||
|
style="width: calc(100% - 100px)"
|
||||||
|
v-model="dialogData.rowData!.executor"
|
||||||
|
>
|
||||||
|
<el-option value="bash" label="bash" />
|
||||||
|
<el-option value="python" label="python" />
|
||||||
|
<el-option value="sh" label="sh" />
|
||||||
|
</el-select>
|
||||||
|
<el-input
|
||||||
|
clearable
|
||||||
|
v-else
|
||||||
|
style="width: calc(100% - 100px)"
|
||||||
|
v-model="dialogData.rowData!.executor"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-form-item :label="$t('cronjob.shellContent')" prop="script" class="mt-5">
|
||||||
|
<el-radio-group v-model="dialogData.rowData!.scriptMode">
|
||||||
|
<el-radio value="input">{{ $t('commons.button.edit') }}</el-radio>
|
||||||
|
<el-radio value="select">{{ $t('container.pathSelect') }}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<CodemirrorPro
|
||||||
|
v-if="dialogData.rowData!.scriptMode=== 'input'"
|
||||||
|
v-model="dialogData.rowData!.script"
|
||||||
|
placeholder="#Define or paste the content of your shell file here"
|
||||||
|
mode="javascript"
|
||||||
|
:heightDiff="400"
|
||||||
|
/>
|
||||||
|
<el-input
|
||||||
|
v-if="dialogData.rowData!.scriptMode=== 'select'"
|
||||||
|
:placeholder="$t('commons.example') + '/tmp/test.sh'"
|
||||||
|
v-model="dialogData.rowData!.script"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<FileList @choose="loadScriptDir" :dir="false"></FileList>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<el-form-item :label="$t('cronjob.shellContent')" v-else prop="script" class="mt-5">
|
||||||
|
<CodemirrorPro
|
||||||
|
v-if="dialogData.rowData!.scriptMode=== 'input'"
|
||||||
|
v-model="dialogData.rowData!.script"
|
||||||
|
placeholder="#Define or paste the content of your shell file here"
|
||||||
|
mode="javascript"
|
||||||
|
:heightDiff="400"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-button class="mb-3" @click="handleSpecCustomAdd()">
|
|
||||||
{{ $t('commons.button.add') }}
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form-item v-if="hasScript()">
|
|
||||||
<el-checkbox v-model="dialogData.rowData!.inContainer">
|
|
||||||
{{ $t('cronjob.containerCheckBox') }}
|
|
||||||
</el-checkbox>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="hasScript() && dialogData.rowData!.inContainer"
|
|
||||||
:label="$t('cronjob.containerName')"
|
|
||||||
prop="containerName"
|
|
||||||
>
|
|
||||||
<el-select class="selectClass" v-model="dialogData.rowData!.containerName">
|
|
||||||
<el-option v-for="item in containerOptions" :key="item" :value="item" :label="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item
|
|
||||||
v-if="hasScript() && dialogData.rowData!.inContainer"
|
|
||||||
:label="$t('container.command')"
|
|
||||||
prop="command"
|
|
||||||
:rules="Rules.requiredInput"
|
|
||||||
>
|
|
||||||
<el-checkbox class="w-full" border v-model="dialogData.rowData!.isCustom">
|
|
||||||
{{ $t('container.custom') }}
|
|
||||||
</el-checkbox>
|
|
||||||
<el-select style="width: calc(100% - 100px)" filterable clearable v-model="dialogData.rowData!.command">
|
|
||||||
<el-option value="ash" label="/bin/ash" />
|
|
||||||
<el-option value="bash" label="/bin/bash" />
|
|
||||||
<el-option value="sh" label="/bin/sh" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item v-if="hasScript()" :label="$t('cronjob.shellContent')" prop="script">
|
|
||||||
<el-input clearable type="textarea" :rows="5" v-model="dialogData.rowData!.script" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="dialogData.rowData!.type === 'website' || dialogData.rowData!.type === 'cutWebsiteLog'"
|
v-if="dialogData.rowData!.type === 'website' || dialogData.rowData!.type === 'cutWebsiteLog'"
|
||||||
:label="dialogData.rowData!.type === 'website' ? $t('cronjob.website'):$t('website.website')"
|
:label="dialogData.rowData!.type === 'website' ? $t('cronjob.website'):$t('website.website')"
|
||||||
@ -383,6 +485,7 @@ import i18n from '@/lang';
|
|||||||
import { ElForm } from 'element-plus';
|
import { ElForm } from 'element-plus';
|
||||||
import { Cronjob } from '@/api/interface/cronjob';
|
import { Cronjob } from '@/api/interface/cronjob';
|
||||||
import { addCronjob, editCronjob, loadNextHandle } from '@/api/modules/cronjob';
|
import { addCronjob, editCronjob, loadNextHandle } from '@/api/modules/cronjob';
|
||||||
|
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
|
||||||
import { listDbItems } from '@/api/modules/database';
|
import { listDbItems } from '@/api/modules/database';
|
||||||
import { GetWebsiteOptions } from '@/api/modules/website';
|
import { GetWebsiteOptions } from '@/api/modules/website';
|
||||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
@ -398,6 +501,7 @@ import {
|
|||||||
transSpecToObj,
|
transSpecToObj,
|
||||||
weekOptions,
|
weekOptions,
|
||||||
} from './../helper';
|
} from './../helper';
|
||||||
|
import { loadUsers } from '@/api/modules/toolbox';
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
interface DialogProps {
|
interface DialogProps {
|
||||||
@ -428,6 +532,7 @@ const acceptParams = (params: DialogProps): void => {
|
|||||||
dialogData.value.rowData.specs = dialogData.value.rowData.specs || [];
|
dialogData.value.rowData.specs = dialogData.value.rowData.specs || [];
|
||||||
if (dialogData.value.title === 'create') {
|
if (dialogData.value.title === 'create') {
|
||||||
changeType();
|
changeType();
|
||||||
|
dialogData.value.rowData.scriptMode = 'input';
|
||||||
dialogData.value.rowData.dbType = 'mysql';
|
dialogData.value.rowData.dbType = 'mysql';
|
||||||
dialogData.value.rowData.downloadAccountID = 1;
|
dialogData.value.rowData.downloadAccountID = 1;
|
||||||
}
|
}
|
||||||
@ -442,7 +547,14 @@ const acceptParams = (params: DialogProps): void => {
|
|||||||
dialogData.value.rowData!.isCustom =
|
dialogData.value.rowData!.isCustom =
|
||||||
dialogData.value.rowData!.command !== 'sh' &&
|
dialogData.value.rowData!.command !== 'sh' &&
|
||||||
dialogData.value.rowData!.command !== 'bash' &&
|
dialogData.value.rowData!.command !== 'bash' &&
|
||||||
dialogData.value.rowData!.command === 'ash';
|
dialogData.value.rowData!.command !== 'ash';
|
||||||
|
|
||||||
|
dialogData.value.rowData!.executor = dialogData.value.rowData!.executor || 'bash';
|
||||||
|
dialogData.value.rowData!.isCustom =
|
||||||
|
dialogData.value.rowData!.executor !== 'sh' &&
|
||||||
|
dialogData.value.rowData!.executor !== 'bash' &&
|
||||||
|
dialogData.value.rowData!.executor !== 'python' &&
|
||||||
|
dialogData.value.rowData!.executor !== 'python3';
|
||||||
|
|
||||||
title.value = i18n.global.t('cronjob.' + dialogData.value.title);
|
title.value = i18n.global.t('cronjob.' + dialogData.value.title);
|
||||||
if (dialogData.value?.rowData?.exclusionRules) {
|
if (dialogData.value?.rowData?.exclusionRules) {
|
||||||
@ -454,6 +566,7 @@ const acceptParams = (params: DialogProps): void => {
|
|||||||
drawerVisible.value = true;
|
drawerVisible.value = true;
|
||||||
loadBackups();
|
loadBackups();
|
||||||
loadAppInstalls();
|
loadAppInstalls();
|
||||||
|
loadShellUsers();
|
||||||
loadWebsites();
|
loadWebsites();
|
||||||
loadContainers();
|
loadContainers();
|
||||||
if (dialogData.value.rowData?.dbType) {
|
if (dialogData.value.rowData?.dbType) {
|
||||||
@ -477,6 +590,7 @@ const websiteOptions = ref([]);
|
|||||||
const backupOptions = ref([]);
|
const backupOptions = ref([]);
|
||||||
const accountOptions = ref([]);
|
const accountOptions = ref([]);
|
||||||
const appOptions = ref([]);
|
const appOptions = ref([]);
|
||||||
|
const userOptions = ref([]);
|
||||||
|
|
||||||
const dbInfo = reactive({
|
const dbInfo = reactive({
|
||||||
isExist: false,
|
isExist: false,
|
||||||
@ -485,6 +599,14 @@ const dbInfo = reactive({
|
|||||||
dbs: [] as Array<Database.DbItem>,
|
dbs: [] as Array<Database.DbItem>,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const verifyScript = (rule: any, value: any, callback: any) => {
|
||||||
|
if (!dialogData.value.rowData!.script || dialogData.value.rowData!.script.length === 0) {
|
||||||
|
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
|
||||||
const verifySpec = (rule: any, value: any, callback: any) => {
|
const verifySpec = (rule: any, value: any, callback: any) => {
|
||||||
if (dialogData.value.rowData!.specObjs.length === 0) {
|
if (dialogData.value.rowData!.specObjs.length === 0) {
|
||||||
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
callback(new Error(i18n.global.t('commons.rule.requiredInput')));
|
||||||
@ -583,7 +705,7 @@ const rules = reactive({
|
|||||||
{ validator: verifySpec, trigger: 'change', required: true },
|
{ validator: verifySpec, trigger: 'change', required: true },
|
||||||
],
|
],
|
||||||
|
|
||||||
script: [Rules.requiredInput],
|
script: [{ validator: verifyScript, trigger: 'blur', required: true }],
|
||||||
website: [Rules.requiredSelect],
|
website: [Rules.requiredSelect],
|
||||||
dbName: [Rules.requiredSelect],
|
dbName: [Rules.requiredSelect],
|
||||||
url: [Rules.requiredInput],
|
url: [Rules.requiredInput],
|
||||||
@ -600,6 +722,10 @@ const loadDir = async (path: string) => {
|
|||||||
dialogData.value.rowData!.sourceDir = path;
|
dialogData.value.rowData!.sourceDir = path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadScriptDir = async (path: string) => {
|
||||||
|
dialogData.value.rowData!.script = path;
|
||||||
|
};
|
||||||
|
|
||||||
const hasDay = (item: any) => {
|
const hasDay = (item: any) => {
|
||||||
return item.specType === 'perMonth' || item.specType === 'perNDay';
|
return item.specType === 'perMonth' || item.specType === 'perNDay';
|
||||||
};
|
};
|
||||||
@ -724,6 +850,11 @@ const changeAccount = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const loadShellUsers = async () => {
|
||||||
|
const res = await loadUsers();
|
||||||
|
userOptions.value = res.data || [];
|
||||||
|
};
|
||||||
|
|
||||||
const loadAppInstalls = async () => {
|
const loadAppInstalls = async () => {
|
||||||
const res = await ListAppInstalled();
|
const res = await ListAppInstalled();
|
||||||
appOptions.value = res.data || [];
|
appOptions.value = res.data || [];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user