feat: 计划任务容器中执行增加 Command 选项 (#4398)

Refs #4363
This commit is contained in:
ssongliu 2024-04-03 16:50:07 +08:00 committed by GitHub
parent 8a011b1cf9
commit 1088034a5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 50 additions and 2 deletions

View file

@ -8,6 +8,7 @@ type CronjobCreate struct {
Spec string `json:"spec" validate:"required"` Spec string `json:"spec" validate:"required"`
Script string `json:"script"` Script string `json:"script"`
Command string `json:"command"`
ContainerName string `json:"containerName"` ContainerName string `json:"containerName"`
AppID string `json:"appID"` AppID string `json:"appID"`
Website string `json:"website"` Website string `json:"website"`
@ -28,6 +29,7 @@ type CronjobUpdate struct {
Spec string `json:"spec" validate:"required"` Spec string `json:"spec" validate:"required"`
Script string `json:"script"` Script string `json:"script"`
Command string `json:"command"`
ContainerName string `json:"containerName"` ContainerName string `json:"containerName"`
AppID string `json:"appID"` AppID string `json:"appID"`
Website string `json:"website"` Website string `json:"website"`
@ -70,6 +72,7 @@ type CronjobInfo struct {
Spec string `json:"spec"` Spec string `json:"spec"`
Script string `json:"script"` Script string `json:"script"`
Command string `json:"command"`
ContainerName string `json:"containerName"` ContainerName string `json:"containerName"`
AppID string `json:"appID"` AppID string `json:"appID"`
Website string `json:"website"` Website string `json:"website"`

View file

@ -9,6 +9,7 @@ type Cronjob struct {
Type string `gorm:"type:varchar(64);not null" json:"type"` Type string `gorm:"type:varchar(64);not null" json:"type"`
Spec string `gorm:"type:varchar(64);not null" json:"spec"` Spec string `gorm:"type:varchar(64);not null" json:"spec"`
Command string `gorm:"type:varchar(64)" json:"command"`
ContainerName string `gorm:"type:varchar(64)" json:"containerName"` ContainerName string `gorm:"type:varchar(64)" json:"containerName"`
Script string `gorm:"longtext" json:"script"` Script string `gorm:"longtext" json:"script"`
Website string `gorm:"type:varchar(64)" json:"website"` Website string `gorm:"type:varchar(64)" json:"website"`

View file

@ -265,6 +265,7 @@ func (u *CronjobService) Update(id uint, req dto.CronjobUpdate) error {
upMap["name"] = req.Name upMap["name"] = req.Name
upMap["spec"] = spec upMap["spec"] = spec
upMap["script"] = req.Script upMap["script"] = req.Script
upMap["command"] = req.Command
upMap["container_name"] = req.ContainerName upMap["container_name"] = req.ContainerName
upMap["app_id"] = req.AppID upMap["app_id"] = req.AppID
upMap["website"] = req.Website upMap["website"] = req.Website

View file

@ -38,7 +38,11 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
_ = cronjobRepo.UpdateRecords(record.ID, map[string]interface{}{"records": record.Records}) _ = cronjobRepo.UpdateRecords(record.ID, map[string]interface{}{"records": record.Records})
script := cronjob.Script script := cronjob.Script
if len(cronjob.ContainerName) != 0 { if len(cronjob.ContainerName) != 0 {
script = fmt.Sprintf("docker exec %s %s", cronjob.ContainerName, cronjob.Script) 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) err = u.handleShell(cronjob.Type, cronjob.Name, script, record.Records)
u.removeExpiredLog(*cronjob) u.removeExpiredLog(*cronjob)

View file

@ -76,6 +76,7 @@ func Init() {
migrations.AddSnapshotIgnore, migrations.AddSnapshotIgnore,
migrations.AddDatabaseIsDelete, migrations.AddDatabaseIsDelete,
migrations.AddXpackHideMenu, migrations.AddXpackHideMenu,
migrations.AddCronjobCommand,
}) })
if err := m.Migrate(); err != nil { if err := m.Migrate(); err != nil {
global.LOG.Error(err) global.LOG.Error(err)

View file

@ -35,3 +35,13 @@ var AddXpackHideMenu = &gormigrate.Migration{
return nil return nil
}, },
} }
var AddCronjobCommand = &gormigrate.Migration{
ID: "20240403-add-cronjob-command",
Migrate: func(tx *gorm.DB) error {
if err := tx.AutoMigrate(&model.Cronjob{}); err != nil {
return err
}
return nil
},
}

View file

@ -9,6 +9,8 @@ export namespace Cronjob {
specObjs: Array<SpecObj>; specObjs: Array<SpecObj>;
script: string; script: string;
isCustom: boolean;
command: string;
inContainer: boolean; inContainer: boolean;
containerName: string; containerName: string;
appID: string; appID: string;

View file

@ -82,7 +82,7 @@ const acceptParams = async (params: DialogProps): Promise<void> => {
title.value = params.container; title.value = params.container;
form.isCustom = false; form.isCustom = false;
form.user = ''; form.user = '';
form.command = '/bin/bash'; form.command = '/bin/sh';
terminalOpen.value = false; terminalOpen.value = false;
}; };

View file

@ -152,6 +152,26 @@
<el-option v-for="item in containerOptions" :key="item" :value="item" :label="item" /> <el-option v-for="item in containerOptions" :key="item" :value="item" :label="item" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item
v-if="hasScript() && dialogData.rowData!.inContainer"
:label="$t('container.command')"
prop="command"
:rules="Rules.requiredInput"
>
<el-checkbox style="width: 100px" 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-form-item v-if="hasScript()" :label="$t('cronjob.shellContent')" prop="script">
<el-input clearable type="textarea" :rows="5" v-model="dialogData.rowData!.script" /> <el-input clearable type="textarea" :rows="5" v-model="dialogData.rowData!.script" />
@ -374,6 +394,12 @@ const acceptParams = (params: DialogProps): void => {
if (dialogData.value.rowData.backupAccounts) { if (dialogData.value.rowData.backupAccounts) {
dialogData.value.rowData.backupAccountList = dialogData.value.rowData.backupAccounts.split(','); dialogData.value.rowData.backupAccountList = dialogData.value.rowData.backupAccounts.split(',');
} }
dialogData.value.rowData!.command = dialogData.value.rowData!.command || 'sh';
dialogData.value.rowData!.isCustom =
dialogData.value.rowData!.command !== 'sh' &&
dialogData.value.rowData!.command !== 'bash' &&
dialogData.value.rowData!.command === 'ash';
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) {
dialogData.value.rowData.exclusionRules = dialogData.value.rowData.exclusionRules.replaceAll(',', '\n'); dialogData.value.rowData.exclusionRules = dialogData.value.rowData.exclusionRules.replaceAll(',', '\n');