Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 计划任务脚本执行增加容器中选项 #1474

Merged
merged 1 commit into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions backend/app/api/v1/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 获取编排列表分页
Expand Down
3 changes: 3 additions & 0 deletions backend/app/dto/cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand All @@ -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"`
Expand Down Expand Up @@ -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"`
Expand Down
1 change: 1 addition & 0 deletions backend/app/model/cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
22 changes: 22 additions & 0 deletions backend/app/service/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions backend/app/service/cornjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion backend/app/service/cronjob_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion backend/init/migration/migrations/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions backend/router/ro_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/api/interface/cronjob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export namespace Cronjob {
second: number;

script: string;
inContainer: boolean;
containerName: string;
website: string;
exclusionRules: string;
dbName: string;
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/api/modules/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`);
};
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/lang/modules/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/lang/modules/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,8 @@ const message = {
taskType: '任务类型',
record: '报告',
shell: 'Shell 脚本',
containerCheckBox: '在容器中执行(无需再输入进入容器命令)',
containerName: '容器名称',
ntp: '时间同步',
website: '备份网站',
rulesHelper: '当存在多个压缩排除规则时,需要换行显示,例:\n*.log \n*.sql',
Expand Down
33 changes: 31 additions & 2 deletions frontend/src/views/cronjob/operate/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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 }>();

Expand All @@ -243,6 +263,7 @@ const handleClose = () => {

const localDirID = ref();

const containerOptions = ref();
const websiteOptions = ref();
const backupOptions = ref();

Expand Down Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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', ',');
}
Expand Down