diff --git a/spug_api/apps/deploy/models.py b/spug_api/apps/deploy/models.py index 2cd7ed0..3070efd 100644 --- a/spug_api/apps/deploy/models.py +++ b/spug_api/apps/deploy/models.py @@ -47,7 +47,7 @@ class DeployRequest(models.Model, ModelMixin): @property def is_quick_deploy(self): - if self.deploy.extend == '1' and self.extra: + if self.type == '1' and self.deploy.extend == '1' and self.extra: extra = json.loads(self.extra) return extra[0] in ('branch', 'tag') return False diff --git a/spug_api/apps/deploy/urls.py b/spug_api/apps/deploy/urls.py index 1fdb7be..424dd04 100644 --- a/spug_api/apps/deploy/urls.py +++ b/spug_api/apps/deploy/urls.py @@ -7,6 +7,7 @@ from .views import * urlpatterns = [ path('request/', RequestView.as_view()), + path('request/info/', get_request_info), path('request/ext1/', post_request_ext1), path('request/ext1/rollback/', post_request_ext1_rollback), path('request/ext2/', post_request_ext2), diff --git a/spug_api/apps/deploy/utils.py b/spug_api/apps/deploy/utils.py index 3d1b9d9..b826162 100644 --- a/spug_api/apps/deploy/utils.py +++ b/spug_api/apps/deploy/utils.py @@ -173,25 +173,28 @@ def _deploy_ext1_host(req, helper, h_id, env): f'mkdir -p {extend.dst_repo} && [ -e {extend.dst_dir} ] && [ ! -L {extend.dst_dir} ]') if code == 0: helper.send_error(host.id, f'检测到该主机的发布目录 {extend.dst_dir!r} 已存在,为了数据安全请自行备份后删除该目录,Spug 将会创建并接管该目录。') - # clean - clean_command = f'ls -d {extend.deploy_id}_* 2> /dev/null | sort -t _ -rnk2 | tail -n +{extend.versions + 1} | xargs rm -rf' - helper.remote_raw(host.id, ssh, f'cd {extend.dst_repo} && {clean_command}') - # transfer files - tar_gz_file = f'{req.spug_version}.tar.gz' - try: - ssh.put_file(os.path.join(REPOS_DIR, 'build', tar_gz_file), os.path.join(extend.dst_repo, tar_gz_file)) - except Exception as e: - helper.send_error(host.id, f'Exception: {e}') + if req.type == '1': + # clean + clean_command = f'ls -d {extend.deploy_id}_* 2> /dev/null | sort -t _ -rnk2 | tail -n +{extend.versions + 1} | xargs rm -rf' + helper.remote_raw(host.id, ssh, f'cd {extend.dst_repo} && {clean_command}') + # transfer files + tar_gz_file = f'{req.spug_version}.tar.gz' + try: + ssh.put_file(os.path.join(REPOS_DIR, 'build', tar_gz_file), os.path.join(extend.dst_repo, tar_gz_file)) + except Exception as e: + helper.send_error(host.id, f'Exception: {e}') - command = f'cd {extend.dst_repo} && rm -rf {req.spug_version} && tar xf {tar_gz_file} && rm -f {req.deploy_id}_*.tar.gz' - helper.remote_raw(host.id, ssh, command) - helper.send_step(h_id, 1, '\033[32m完成√\033[0m\r\n') + command = f'cd {extend.dst_repo} && rm -rf {req.spug_version} && tar xf {tar_gz_file} && rm -f {req.deploy_id}_*.tar.gz' + helper.remote_raw(host.id, ssh, command) + helper.send_step(h_id, 1, '\033[32m完成√\033[0m\r\n') + else: + helper.send_step(h_id, 1, '\033[33m跳过√\033[0m\r\n') # pre host repo_dir = os.path.join(extend.dst_repo, req.spug_version) if extend.hook_pre_host: helper.send_step(h_id, 2, f'{human_time()} 发布前任务... \r\n') - command = f'cd {repo_dir} ; {extend.hook_pre_host}' + command = f'cd {repo_dir} && {extend.hook_pre_host}' helper.remote(host.id, ssh, command) # do deploy @@ -202,7 +205,7 @@ def _deploy_ext1_host(req, helper, h_id, env): # post host if extend.hook_post_host: helper.send_step(h_id, 4, f'{human_time()} 发布后任务... \r\n') - command = f'cd {extend.dst_dir} ; {extend.hook_post_host}' + command = f'cd {extend.dst_dir} && {extend.hook_post_host}' helper.remote(host.id, ssh, command) helper.send_step(h_id, 100, f'\r\n{human_time()} ** \033[32m发布成功\033[0m **') @@ -237,7 +240,7 @@ def _deploy_ext2_host(helper, h_id, actions, env, spug_version): command += f'&& rm -rf {action["dst"]} && mv /tmp/{spug_version}/{sd_dst} {action["dst"]} ' command += f'&& rm -rf /tmp/{spug_version}* && echo "transfer completed"' else: - command = f'cd /tmp ; {action["data"]}' + command = f'cd /tmp && {action["data"]}' helper.remote(host.id, ssh, command) helper.send_step(h_id, 100, f'\r\n{human_time()} ** \033[32m发布成功\033[0m **') diff --git a/spug_api/apps/deploy/views.py b/spug_api/apps/deploy/views.py index 7bef9ec..1b0f7b2 100644 --- a/spug_api/apps/deploy/views.py +++ b/spug_api/apps/deploy/views.py @@ -334,6 +334,18 @@ def post_request_ext2(request): return json_response(error=error) +def get_request_info(request): + form, error = JsonParser( + Argument('id', type=int, help='参数错误') + ).parse(request.GET) + if error is None: + req = DeployRequest.objects.get(pk=form.id) + response = req.to_dict(selects=('status', 'reason')) + response['status_alias'] = req.get_status_display() + return json_response(response) + return json_response(error=error) + + def do_upload(request): repos_dir = settings.REPOS_DIR file = request.FILES['file'] diff --git a/spug_web/src/pages/deploy/request/Ext1Console.js b/spug_web/src/pages/deploy/request/Ext1Console.js index 4e5117b..fc73a4f 100644 --- a/spug_web/src/pages/deploy/request/Ext1Console.js +++ b/spug_web/src/pages/deploy/request/Ext1Console.js @@ -15,6 +15,8 @@ import store from './store'; function Ext1Console(props) { const outputs = useLocalStore(() => ({})); const terms = useLocalStore(() => ({})); + const [mini, setMini] = useState(false); + const [visible, setVisible] = useState(true); const [fetching, setFetching] = useState(true); useEffect(props.request.mode === 'read' ? readDeploy : doDeploy, []) @@ -39,7 +41,7 @@ function Ext1Console(props) { Object.assign(outputs, res.outputs) setTimeout(() => setFetching(false), 100) socket = _makeSocket() - store.fetchRecords() + store.fetchInfo(props.request.id) }) return () => socket && socket.close() } @@ -85,8 +87,8 @@ function Ext1Console(props) { } function switchMiniMode() { - const value = store.tabModes[props.request.id]; - store.tabModes[props.request.id] = !value + setMini(true) + setVisible(false) } function handleSetTerm(term, key) { @@ -97,86 +99,90 @@ function Ext1Console(props) { } let {local, ...hosts} = outputs; - return store.tabModes[props.request.id] ? ( - -
-
{props.request.name}
- store.showConsole(props.request, true)}/> -
- {local && ( - - )} - {Object.values(hosts).map(item => ( - - ))} -
- ) : ( - store.showConsole(props.request, true)} - title={[ - {props.request.name}, -
- -
- ]}> - - {local && ( - - - - - - - - - - - - )}> - handleSetTerm(term, 'local')}/> - - - )} - - }> - {Object.entries(hosts).map(([key, item], index) => ( - - {item.title} - - - - - - - - }> - handleSetTerm(term, key)}/> - + return ( +
+ {mini && ( + setVisible(true)}> +
+
{props.request.name}
+ store.showConsole(props.request, true)}/> +
+ {local && ( + + )} + {Object.values(hosts).map(item => ( + ))} - - - +
+ )} + store.showConsole(props.request, true)} + title={[ + {props.request.name}, +
+ +
+ ]}> + + {local && ( + + + + + + + + + + +
+ )}> + handleSetTerm(term, 'local')}/> + +
+ )} + + }> + {Object.entries(hosts).map(([key, item], index) => ( + + {item.title} + + + + + + + + }> + handleSetTerm(term, key)}/> + + ))} + +
+
+ ) + } export default observer(Ext1Console) \ No newline at end of file diff --git a/spug_web/src/pages/deploy/request/Ext2Console.js b/spug_web/src/pages/deploy/request/Ext2Console.js index f4f7b8f..45c60f2 100644 --- a/spug_web/src/pages/deploy/request/Ext2Console.js +++ b/spug_web/src/pages/deploy/request/Ext2Console.js @@ -17,6 +17,8 @@ function Ext2Console(props) { const outputs = useLocalStore(() => ({local: {id: 'local'}})); const [sActions, setSActions] = useState([]); const [hActions, setHActions] = useState([]); + const [mini, setMini] = useState(false); + const [visible, setVisible] = useState(true); const [fetching, setFetching] = useState(true); useEffect(props.request.mode === 'read' ? readDeploy : doDeploy, []) @@ -45,6 +47,7 @@ function Ext2Console(props) { Object.assign(outputs, res.outputs) setTimeout(() => setFetching(false), 100) socket = _makeSocket() + store.fetchInfo(props.request.id) }) return () => socket && socket.close() } @@ -92,8 +95,8 @@ function Ext2Console(props) { } function switchMiniMode() { - const value = store.tabModes[props.request.id]; - store.tabModes[props.request.id] = !value + setMini(true) + setVisible(false) } function handleSetTerm(term, key) { @@ -104,81 +107,84 @@ function Ext2Console(props) { } const hostOutputs = Object.values(outputs).filter(x => x.id !== 'local'); - return store.tabModes[props.request.id] ? ( - -
-
{props.request.name}
- store.showConsole(props.request, true)}/> -
- - {Object.values(outputs).filter(x => x.id !== 'local').map(item => ( - - ))} -
- ) : ( - store.showConsole(props.request, true)} - title={[ - {props.request.name}, -
- -
- ]}> - - - - - - - {sActions.map((item, index) => ( - - ))} - - - )}> - handleSetTerm(term, 'local')}/> - - - {hostOutputs.length > 0 && ( - }> - {hostOutputs.map((item, index) => ( - - {item.title} - - - {hActions.map((action, index) => ( - - ))} - - }> - handleSetTerm(term, item.id)}/> - - ))} + return ( +
+ {mini && ( + setVisible(true)}> +
+
{props.request.name}
+ store.showConsole(props.request, true)}/> +
+ + {Object.values(outputs).filter(x => x.id !== 'local').map(item => ( + + ))} +
+ )} + store.showConsole(props.request, true)} + title={[ + {props.request.name}, +
+ +
+ ]}> + + + + + + + {sActions.map((item, index) => ( + + ))} + +
+ )}> + handleSetTerm(term, 'local')}/> +
- )} -
-
+ {hostOutputs.length > 0 && ( + }> + {hostOutputs.map((item, index) => ( + + {item.title} + + + {hActions.map((action, index) => ( + + ))} + + }> + handleSetTerm(term, item.id)}/> + + ))} + + )} + + + ) } diff --git a/spug_web/src/pages/deploy/request/Table.js b/spug_web/src/pages/deploy/request/Table.js index 10c7fe6..6a92674 100644 --- a/spug_web/src/pages/deploy/request/Table.js +++ b/spug_web/src/pages/deploy/request/Table.js @@ -9,7 +9,6 @@ import { BranchesOutlined, BuildOutlined, TagOutlined, PlusOutlined, TagsOutline import { Radio, Modal, Popover, Tag, Popconfirm, Tooltip, message } from 'antd'; import { http, hasPermission } from 'libs'; import { Action, AuthButton, TableCard } from 'components'; -import styles from './index.module.less'; import store from './store'; function ComTable() { @@ -146,18 +145,7 @@ function ComTable() { } function handleDeploy(e, info) { - const right = document.body.clientWidth - 25 - e.target.getBoundingClientRect().x; - const bottom = document.body.clientHeight - 40 - e.target.getBoundingClientRect().y; - store.box.setAttribute('style', `display: block; bottom: ${bottom}px; right: ${right}px;`); - setTimeout(() => { - store.box.setAttribute('class', `${styles.floatBox} ${styles.floatBoxAnimate}`) - }, 10); - setTimeout(() => { - store.showConsole(info); - store.box.setAttribute('style', 'display: none'); - store.box.setAttribute('class', styles.floatBox) - }, 300) - + store.showConsole(info); } return ( diff --git a/spug_web/src/pages/deploy/request/index.js b/spug_web/src/pages/deploy/request/index.js index 4428e11..dda6c55 100644 --- a/spug_web/src/pages/deploy/request/index.js +++ b/spug_web/src/pages/deploy/request/index.js @@ -90,16 +90,14 @@ function Index() { {store.rollbackVisible && } {store.tabs.length > 0 && ( - {store.tabs.map(item => ( + {store.tabs.map(item => item.id ? item.app_extend === '1' ? ( ) : ( - ) - ))} + ) : null)} )} -
store.box = el} id='floatBox' className={styles.floatBox}/> ) } diff --git a/spug_web/src/pages/deploy/request/index.module.less b/spug_web/src/pages/deploy/request/index.module.less index bd1a5b7..cb1090e 100644 --- a/spug_web/src/pages/deploy/request/index.module.less +++ b/spug_web/src/pages/deploy/request/index.module.less @@ -100,21 +100,4 @@ .upload :global(.ant-upload-list-item) { margin: 0; -} - -.floatBox { - display: none; - position: fixed; - width: 20px; - height: 10px; - transition: right 0.3s, width 0.3s, height0 .3s, bottom 0.3s ease-in-out; - background: rgba(0, 0, 0, 0.1); - border-radius: 5px; -} - -.floatBoxAnimate { - width: 180px; - height: 64px; - bottom: 12px !important; - right: 24px !important; -} +} \ No newline at end of file diff --git a/spug_web/src/pages/deploy/request/store.js b/spug_web/src/pages/deploy/request/store.js index d25f712..abca671 100644 --- a/spug_web/src/pages/deploy/request/store.js +++ b/spug_web/src/pages/deploy/request/store.js @@ -12,9 +12,7 @@ class Store { @observable records = []; @observable record = {}; @observable counter = {}; - @observable box = null; @observable tabs = []; - @observable tabModes = {}; @observable isFetching = false; @observable addVisible = false; @observable ext1Visible = false; @@ -55,6 +53,19 @@ class Store { .finally(() => this.isFetching = false) }; + fetchInfo = (id) => { + http.get('/api/deploy/request/info/', {params: {id}}) + .then(res => { + for (let item of this.records) { + if (item.id === id) { + Object.assign(item, res) + break + } + } + }) + .then(this._updateCounter) + } + _updateCounter = () => { const counter = {'all': 0, '-3': 0, '0': 0, '1': 0, '3': 0, '99': 0}; for (let item of this.records) { @@ -122,18 +133,15 @@ class Store { const index = lds.findIndex(this.tabs, x => x.id === info.id); if (isClose) { if (index !== -1) { - this.tabs.splice(index, 1) - delete this.tabModes[info.id] + this.tabs[index] = {} } - this.fetchRecords() + this.fetchInfo(info.id) } else if (index === -1) { - this.tabModes[info.id] = true this.tabs.push(info) } }; readConsole = (info) => { - this.tabModes[info.id] = false const index = lds.findIndex(this.tabs, x => x.id === info.id); if (index === -1) { info = Object.assign({}, info, {mode: 'read'}) @@ -142,9 +150,7 @@ class Store { }; leaveConsole = () => { - for (let item of this.tabs) { - item.mode = 'read' - } + this.tabs = [] } }