mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-18 22:22:59 +08:00
feat: 计划任务脚本执行增加容器中选项 (#1474)
This commit is contained in:
parent
506d78cb00
commit
c403eb55b1
@ -40,6 +40,23 @@ func (b *BaseApi) SearchContainer(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// @Tags Container
|
||||
// @Summary List containers
|
||||
// @Description 获取容器名称
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /containers/list [post]
|
||||
func (b *BaseApi) ListContainer(c *gin.Context) {
|
||||
list, err := containerService.List()
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
helper.SuccessWithData(c, list)
|
||||
}
|
||||
|
||||
// @Tags Container Compose
|
||||
// @Summary Page composes
|
||||
// @Description 获取编排列表分页
|
||||
|
@ -13,6 +13,7 @@ type CronjobCreate struct {
|
||||
Second int `json:"second" validate:"number"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@ -34,6 +35,7 @@ type CronjobUpdate struct {
|
||||
Second int `json:"second" validate:"number"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
@ -76,6 +78,7 @@ type CronjobInfo struct {
|
||||
Second int `json:"second"`
|
||||
|
||||
Script string `json:"script"`
|
||||
ContainerName string `json:"containerName"`
|
||||
Website string `json:"website"`
|
||||
ExclusionRules string `json:"exclusionRules"`
|
||||
DBName string `json:"dbName"`
|
||||
|
@ -15,6 +15,7 @@ type Cronjob struct {
|
||||
Minute uint64 `gorm:"type:decimal" json:"minute"`
|
||||
Second uint64 `gorm:"type:decimal" json:"second"`
|
||||
|
||||
ContainerName string `gorm:"type:varchar(64)" json:"containerName"`
|
||||
Script string `gorm:"longtext" json:"script"`
|
||||
Website string `gorm:"type:varchar(64)" json:"website"`
|
||||
DBName string `gorm:"type:varchar(64)" json:"dbName"`
|
||||
|
@ -35,6 +35,7 @@ type ContainerService struct{}
|
||||
|
||||
type IContainerService interface {
|
||||
Page(req dto.PageContainer) (int64, interface{}, error)
|
||||
List() ([]string, error)
|
||||
PageNetwork(req dto.SearchWithPage) (int64, interface{}, error)
|
||||
PageVolume(req dto.SearchWithPage) (int64, interface{}, error)
|
||||
ListVolume() ([]dto.Options, error)
|
||||
@ -150,6 +151,27 @@ func (u *ContainerService) Page(req dto.PageContainer) (int64, interface{}, erro
|
||||
return int64(total), backDatas, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) List() ([]string, error) {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
containers, err := client.ContainerList(context.Background(), types.ContainerListOptions{All: true})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var datas []string
|
||||
for _, container := range containers {
|
||||
for _, name := range container.Names {
|
||||
if len(name) != 0 {
|
||||
datas = append(datas, strings.TrimLeft(name, "/"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
func (u *ContainerService) Inspect(req dto.InspectReq) (string, error) {
|
||||
client, err := docker.NewDockerClient()
|
||||
if err != nil {
|
||||
|
@ -238,6 +238,7 @@ func (u *CronjobService) Update(id uint, req dto.CronjobUpdate) error {
|
||||
upMap["name"] = req.Name
|
||||
upMap["spec"] = cronjob.Spec
|
||||
upMap["script"] = req.Script
|
||||
upMap["container_name"] = req.ContainerName
|
||||
upMap["spec_type"] = req.SpecType
|
||||
upMap["week"] = req.Week
|
||||
upMap["day"] = req.Day
|
||||
|
@ -32,7 +32,11 @@ func (u *CronjobService) HandleJob(cronjob *model.Cronjob) {
|
||||
if len(cronjob.Script) == 0 {
|
||||
return
|
||||
}
|
||||
message, err = u.handleShell(cronjob.Type, cronjob.Name, cronjob.Script)
|
||||
if len(cronjob.ContainerName) != 0 {
|
||||
message, err = u.handleShell(cronjob.Type, cronjob.Name, fmt.Sprintf("docker exec %s %s", cronjob.ContainerName, cronjob.Script))
|
||||
} else {
|
||||
message, err = u.handleShell(cronjob.Type, cronjob.Name, cronjob.Script)
|
||||
}
|
||||
u.HandleRmExpired("LOCAL", "", "", cronjob, nil)
|
||||
case "curl":
|
||||
if len(cronjob.URL) == 0 {
|
||||
|
@ -394,7 +394,7 @@ var UpdateWebsite = &gormigrate.Migration{
|
||||
var AddBackupAccountDir = &gormigrate.Migration{
|
||||
ID: "20200620-add-backup-dir",
|
||||
Migrate: func(tx *gorm.DB) error {
|
||||
if err := tx.AutoMigrate(&model.BackupAccount{}); err != nil {
|
||||
if err := tx.AutoMigrate(&model.BackupAccount{}, &model.Cronjob{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
@ -23,6 +23,7 @@ func (s *ContainerRouter) InitContainerRouter(Router *gin.RouterGroup) {
|
||||
baRouter.POST("/upgrade", baseApi.ContainerUpgrade)
|
||||
baRouter.POST("/info", baseApi.ContainerInfo)
|
||||
baRouter.POST("/search", baseApi.SearchContainer)
|
||||
baRouter.POST("/list", baseApi.ListContainer)
|
||||
baRouter.GET("/search/log", baseApi.ContainerLogs)
|
||||
baRouter.GET("/limit", baseApi.LoadResouceLimit)
|
||||
baRouter.POST("/clean/log", baseApi.CleanContainerLog)
|
||||
|
@ -13,6 +13,8 @@ export namespace Cronjob {
|
||||
second: number;
|
||||
|
||||
script: string;
|
||||
inContainer: boolean;
|
||||
containerName: string;
|
||||
website: string;
|
||||
exclusionRules: string;
|
||||
dbName: string;
|
||||
|
@ -5,6 +5,9 @@ import { Container } from '../interface/container';
|
||||
export const searchContainer = (params: Container.ContainerSearch) => {
|
||||
return http.post<ResPage<Container.ContainerInfo>>(`/containers/search`, params, 400000);
|
||||
};
|
||||
export const listContainer = () => {
|
||||
return http.post<Array<string>>(`/containers/list`, {});
|
||||
};
|
||||
export const loadResourceLimit = () => {
|
||||
return http.get<Container.ResourceLimit>(`/containers/limit`);
|
||||
};
|
||||
|
@ -661,6 +661,8 @@ const message = {
|
||||
taskType: 'Task type',
|
||||
record: 'Records',
|
||||
shell: 'Shell script',
|
||||
containerCheckBox: 'In container (no need to enter the container command)',
|
||||
containerName: 'Container name',
|
||||
ntp: 'Time synchronization',
|
||||
website: 'Backup website',
|
||||
rulesHelper:
|
||||
|
@ -655,6 +655,8 @@ const message = {
|
||||
taskType: '任务类型',
|
||||
record: '报告',
|
||||
shell: 'Shell 脚本',
|
||||
containerCheckBox: '在容器中执行(无需再输入进入容器命令)',
|
||||
containerName: '容器名称',
|
||||
ntp: '时间同步',
|
||||
website: '备份网站',
|
||||
rulesHelper: '当存在多个压缩排除规则时,需要换行显示,例:\n*.log \n*.sql',
|
||||
|
@ -21,7 +21,7 @@
|
||||
<el-option value="ntp" :label="$t('cronjob.ntp')" />
|
||||
<el-option value="cutWebsiteLog" :label="$t('cronjob.cutWebsiteLog')" />
|
||||
</el-select>
|
||||
<el-tag v-else>{{ dialogData.rowData!.type }}</el-tag>
|
||||
<el-tag v-else>{{ $t('cronjob.' + dialogData.rowData!.type) }}</el-tag>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="$t('cronjob.taskName')" prop="name">
|
||||
@ -75,6 +75,21 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<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()" :label="$t('cronjob.shellContent')" prop="script">
|
||||
<el-input
|
||||
clearable
|
||||
@ -205,6 +220,7 @@ import { GetWebsiteOptions } from '@/api/modules/website';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { listContainer } from '@/api/modules/container';
|
||||
const router = useRouter();
|
||||
|
||||
interface DialogProps {
|
||||
@ -226,10 +242,14 @@ const acceptParams = (params: DialogProps): void => {
|
||||
if (dialogData.value?.rowData?.exclusionRules) {
|
||||
dialogData.value.rowData.exclusionRules = dialogData.value.rowData.exclusionRules.replaceAll(',', '\n');
|
||||
}
|
||||
if (dialogData.value?.rowData?.containerName) {
|
||||
dialogData.value.rowData.inContainer = true;
|
||||
}
|
||||
drawerVisiable.value = true;
|
||||
checkMysqlInstalled();
|
||||
loadBackups();
|
||||
loadWebsites();
|
||||
loadContainers();
|
||||
};
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
@ -243,6 +263,7 @@ const handleClose = () => {
|
||||
|
||||
const localDirID = ref();
|
||||
|
||||
const containerOptions = ref();
|
||||
const websiteOptions = ref();
|
||||
const backupOptions = ref();
|
||||
|
||||
@ -424,7 +445,12 @@ const loadBackups = async () => {
|
||||
|
||||
const loadWebsites = async () => {
|
||||
const res = await GetWebsiteOptions();
|
||||
websiteOptions.value = res.data;
|
||||
websiteOptions.value = res.data || [];
|
||||
};
|
||||
|
||||
const loadContainers = async () => {
|
||||
const res = await listContainer();
|
||||
containerOptions.value = res.data || [];
|
||||
};
|
||||
|
||||
const checkMysqlInstalled = async () => {
|
||||
@ -487,6 +513,9 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
if (!dialogData.value.rowData.inContainer) {
|
||||
dialogData.value.rowData.containerName = '';
|
||||
}
|
||||
if (dialogData.value?.rowData?.exclusionRules) {
|
||||
dialogData.value.rowData.exclusionRules = dialogData.value.rowData.exclusionRules.replaceAll('\n', ',');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user