mirror of https://github.com/openspug/spug
A 自定义发布新增用于文件分发的数据传输动作
parent
467f9e99e1
commit
d5a5ee2340
|
@ -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()} ** 发布成功 **')
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue