A 自定义发布新增用于文件分发的数据传输动作

pull/161/head
vapao 2020-07-23 01:26:10 +08:00
parent 467f9e99e1
commit d5a5ee2340
2 changed files with 87 additions and 14 deletions

View File

@ -125,6 +125,28 @@ def _ext2_deploy(req, helper, env):
helper.local(f'cd /tmp && {action["data"]}', env)
step += 1
helper.send_step('local', 100, '完成\r\n' if step == 2 else '\r\n')
for action in host_actions:
if action.get('type') == 'transfer':
helper.send_info('local', f'{human_time()} 检测到数据传输动作,执行打包... ')
action['src'] = action['src'].rstrip('/ ')
action['dst'] = action['dst'].rstrip('/ ')
if not action['src'] or not action['dst']:
helper.send_error('local', f'invalid path for transfer, src: {action["src"]} dst: {action["dst"]}')
is_dir, exclude = os.path.isdir(action['src']), ''
sp_dir, sd_dst = os.path.split(action['src'])
contain = sd_dst
if action['mode'] != '0' and is_dir:
files = helper.parse_filter_rule(action['rule'], ',')
if files:
if action['mode'] == '1':
contain = ' '.join(f'{sd_dst}/{x}' for x in files)
else:
exclude = ' '.join(f'--exclude={sd_dst}/{x}' for x in files)
tar_gz_file = f'{env.SPUG_VERSION}.tar.gz'
helper.local(f'cd {sp_dir} && rm -f {req.deploy_id}_*.tar.gz && tar zcf {tar_gz_file} {exclude} {contain}')
helper.send_info('local', '完成\r\n')
break
if host_actions:
threads, latest_exception = [], None
with futures.ThreadPoolExecutor(max_workers=min(10, os.cpu_count() + 5)) as executor:
@ -202,7 +224,19 @@ def _deploy_ext2_host(helper, h_id, actions, env):
helper.send_step(h_id, 2, '完成\r\n')
for index, action in enumerate(actions):
helper.send_step(h_id, 2 + index, f'{human_time()} {action["title"]}...\r\n')
helper.remote(host.id, ssh, f'cd /tmp && {action["data"]}', env)
if action.get('type') == 'transfer':
sp_dir, sd_dst = os.path.split(action['src'])
tar_gz_file = f'{env.SPUG_VERSION}.tar.gz'
try:
ssh.put_file(os.path.join(sp_dir, tar_gz_file), f'/tmp/{tar_gz_file}')
except Exception as e:
helper.send_error(host.id, f'exception: {e}')
command = f'cd /tmp && tar xf {tar_gz_file} && rm -f {tar_gz_file} '
command += f'&& rm -rf {action["dst"]} && mv /tmp/{sd_dst} {action["dst"]} && echo "transfer completed"'
else:
command = f'cd /tmp && {action["data"]}'
helper.remote(host.id, ssh, command, env)
helper.send_step(h_id, 100, f'\r\n{human_time()} ** 发布成功 **')

View File

@ -5,13 +5,14 @@
*/
import React from 'react';
import { observer } from 'mobx-react';
import { Form, Input, Button, message, Divider, Alert, Icon } from 'antd';
import { Form, Input, Button, message, Divider, Alert, Icon, Select } from 'antd';
import Editor from 'react-ace';
import 'ace-builds/src-noconflict/mode-sh';
import 'ace-builds/src-noconflict/theme-tomorrow';
import styles from './index.module.css';
import { http, cleanCommand } from 'libs';
import store from './store';
import lds from 'lodash';
@observer
class Ext2Setup3 extends React.Component {
@ -27,7 +28,7 @@ class Ext2Setup3 extends React.Component {
const info = store.deploy;
info['app_id'] = store.app_id;
info['extend'] = '2';
info['host_actions'] = info['host_actions'].filter(x => x.title && x.data);
info['host_actions'] = info['host_actions'].filter(x => (x.title && x.data) || (x.title && x.src && x.dst));
info['server_actions'] = info['server_actions'].filter(x => x.title && x.data);
http.post('/api/app/deploy/', info)
.then(res => {
@ -87,17 +88,48 @@ class Ext2Setup3 extends React.Component {
<Form.Item required label={`目标主机动作${index + 1}`}>
<Input value={item['title']} onChange={e => item['title'] = e.target.value} placeholder="请输入"/>
</Form.Item>
<Form.Item required label="执行内容">
<Editor
mode="sh"
theme="tomorrow"
width="100%"
height="100px"
value={item['data']}
onChange={v => item['data'] = cleanCommand(v)}
placeholder="请输入要执行的动作"/>
</Form.Item>
{item['type'] === 'transfer' ? ([
<Form.Item key={0} label="过滤规则">
<Input
spellCheck={false}
placeholder="请输入逗号分割的过滤规则"
value={item['rule']}
onChange={e => item['rule'] = e.target.value.replace('', ',')}
disabled={item['mode'] === '0'}
addonBefore={(
<Select style={{width: 100}} value={item['mode']} onChange={v => item['mode'] = v}>
<Select.Option value="0">关闭</Select.Option>
<Select.Option value="1">包含</Select.Option>
<Select.Option value="2">排除</Select.Option>
</Select>
)}/>
</Form.Item>,
<Form.Item key={1} required label="传输路径" extra={<a
target="_blank" rel="noopener noreferrer"
href="https://spug.dev/docs/deploy-config#%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93">使用前请务必阅读官方文档</a>}>
<Input
spellCheck={false}
value={item['src']}
placeholder="请输入本地路径部署spug的容器或主机"
onChange={e => item['src'] = e.target.value}/>
<Input
spellCheck={false}
value={item['dst']}
placeholder="请输入目标主机路径"
onChange={e => item['dst'] = e.target.value}/>
</Form.Item>
]) : (
<Form.Item required label="执行内容">
<Editor
mode="sh"
theme="tomorrow"
width="100%"
height="100px"
value={item['data']}
onChange={v => item['data'] = cleanCommand(v)}
placeholder="请输入要执行的动作"/>
</Form.Item>
)}
<div className={styles.delAction} onClick={() => host_actions.splice(index, 1)}>
<Icon type="minus-circle"/>移除
</div>
@ -107,6 +139,13 @@ class Ext2Setup3 extends React.Component {
<Button type="dashed" block onClick={() => host_actions.push({})}>
<Icon type="plus"/>添加目标主机执行动作在部署目标主机执行
</Button>
<Button
block
type="dashed"
disabled={lds.findIndex(host_actions, x => x.type === 'transfer') !== -1}
onClick={() => host_actions.push({type: 'transfer', title: '数据传输', mode: '0'})}>
<Icon type="plus"/>添加数据传输动作仅能添加一个
</Button>
</Form.Item>
<Form.Item wrapperCol={{span: 14, offset: 6}}>
<Button