diff --git a/spug_api/apps/deploy/models.py b/spug_api/apps/deploy/models.py index 6df7992..219e341 100644 --- a/spug_api/apps/deploy/models.py +++ b/spug_api/apps/deploy/models.py @@ -32,6 +32,7 @@ class DeployRequest(models.Model, ModelMixin): reason = models.CharField(max_length=255, null=True) version = models.CharField(max_length=50, null=True) spug_version = models.CharField(max_length=50, null=True) + plan = models.DateTimeField(null=True) created_at = models.CharField(max_length=20, default=human_datetime) created_by = models.ForeignKey(User, models.PROTECT, related_name='+') diff --git a/spug_api/apps/deploy/views.py b/spug_api/apps/deploy/views.py index 3d30d23..6840580 100644 --- a/spug_api/apps/deploy/views.py +++ b/spug_api/apps/deploy/views.py @@ -201,6 +201,7 @@ def post_request_ext1(request): Argument('repository_id', type=int, help='请选择发布版本'), Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'), Argument('type', default='1'), + Argument('plan', required=False), Argument('desc', required=False), ).parse(request.body) if error is None: @@ -232,7 +233,8 @@ def post_request_ext2(request): Argument('name', help='请输申请标题'), Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'), Argument('extra', type=dict, required=False), - Argument('version', required=False), + Argument('version', default=''), + Argument('plan', required=False), Argument('desc', required=False), ).parse(request.body) if error is None: diff --git a/spug_api/apps/schedule/builtin.py b/spug_api/apps/schedule/builtin.py index 71836bf..c6bd2b1 100644 --- a/spug_api/apps/schedule/builtin.py +++ b/spug_api/apps/schedule/builtin.py @@ -6,8 +6,10 @@ from apps.account.models import History from apps.alarm.models import Alarm from apps.schedule.models import Task from apps.deploy.models import DeployRequest -from libs.utils import parse_time +from apps.deploy.utils import dispatch +from libs.utils import parse_time, human_datetime from datetime import datetime, timedelta +from threading import Thread def auto_run_by_day(): @@ -24,8 +26,15 @@ def auto_run_by_day(): def auto_run_by_minute(): + close_old_connections() now = datetime.now() for req in DeployRequest.objects.filter(status='2'): if (now - parse_time(req.do_at)).seconds > 3600: req.status = '-3' req.save() + for req in DeployRequest.objects.filter(status='1', plan__lte=now): + req.status = '2' + req.do_at = human_datetime() + req.do_by = req.created_by + req.save() + Thread(target=dispatch, args=(req,)).start() diff --git a/spug_api/apps/schedule/scheduler.py b/spug_api/apps/schedule/scheduler.py index 0857877..bac7410 100644 --- a/spug_api/apps/schedule/scheduler.py +++ b/spug_api/apps/schedule/scheduler.py @@ -78,7 +78,7 @@ class Scheduler: def _init_builtin_jobs(self): self.scheduler.add_job(auto_run_by_day, 'cron', hour=1, minute=20) - self.scheduler.add_job(auto_run_by_minute, 'interval', minutes=5) + self.scheduler.add_job(auto_run_by_minute, 'interval', minutes=1) def _dispatch(self, task_id, command, targets): close_old_connections() diff --git a/spug_web/src/pages/deploy/request/Ext1Form.js b/spug_web/src/pages/deploy/request/Ext1Form.js index fa63ecb..3b1e9fc 100644 --- a/spug_web/src/pages/deploy/request/Ext1Form.js +++ b/spug_web/src/pages/deploy/request/Ext1Form.js @@ -5,7 +5,7 @@ */ import React, { useState, useEffect } from 'react'; import { observer } from 'mobx-react'; -import { Modal, Form, Input, Select, message, Button } from 'antd'; +import { Modal, Form, Input, Select, DatePicker, message, Button } from 'antd'; import HostSelector from './HostSelector'; import hostStore from 'pages/host/store'; import http from 'libs/http'; @@ -19,6 +19,7 @@ export default observer(function () { const [loading, setLoading] = useState(false); const [versions, setVersions] = useState([]); const [host_ids, setHostIds] = useState([]); + const [plan, setPlan] = useState(store.record.plan); useEffect(() => { const {deploy_id, app_host_ids, host_ids} = store.record; @@ -38,6 +39,7 @@ export default observer(function () { formData['host_ids'] = host_ids; formData['type'] = store.record.type; formData['deploy_id'] = store.record.deploy_id; + if (plan) formData.plan = plan.format('YYYY-MM-DD HH:mm:00'); http.post('/api/deploy/request/ext1/', formData) .then(res => { message.success('操作成功'); @@ -46,7 +48,7 @@ export default observer(function () { }, () => setLoading(false)) } - const {app_host_ids, type, rb_id,} = store.record; + const {app_host_ids, type, rb_id} = store.record; return ( store.ext1Visible = false} confirmLoading={loading} onOk={handleSubmit}> -
+ @@ -79,6 +81,18 @@ export default observer(function () { + {type !== '2' && ( + + + {plan ? 大约 {plan.fromNow()} : null} + + )}
{visible && { const {app_host_ids, host_ids, extra} = store.record; @@ -38,6 +39,7 @@ export default observer(function () { formData['id'] = store.record.id; formData['host_ids'] = host_ids; formData['deploy_id'] = store.record.deploy_id; + if (plan) formData.plan = plan.format('YYYY-MM-DD HH:mm:00'); if (fileList.length > 0) formData['extra'] = lds.pick(fileList[0], ['path', 'name']); http.post('/api/deploy/request/ext2/', formData) .then(res => { @@ -67,17 +69,17 @@ export default observer(function () { return false } - const {app_host_ids, deploy_id} = store.record; + const {app_host_ids, deploy_id, type} = store.record; return ( store.ext2Visible = false} confirmLoading={loading} onOk={handleSubmit}> -
+ @@ -100,6 +102,18 @@ export default observer(function () { + {type !== '2' && ( + + + {plan ? 大约 {plan.fromNow()} : null} + + )}
{visible && (
- {info.type === '2' && R} + {info.type === '2' && R} + {info.plan && P} {info.name}
) diff --git a/spug_web/src/pages/deploy/request/store.js b/spug_web/src/pages/deploy/request/store.js index c97b008..0948112 100644 --- a/spug_web/src/pages/deploy/request/store.js +++ b/spug_web/src/pages/deploy/request/store.js @@ -5,6 +5,7 @@ */ import { observable, computed } from "mobx"; import http from 'libs/http'; +import moment from 'moment'; import lds from 'lodash'; class Store { @@ -106,6 +107,7 @@ class Store { showForm = (info) => { this.record = info; + if (info.plan) this.record.plan = moment(info.plan); if (info['app_extend'] === '1') { this.ext1Visible = true } else {