mirror of https://github.com/openspug/spug
U 自动移除命令中换行包含的\r
parent
e285faf080
commit
17dfe2618d
|
@ -26,6 +26,11 @@ export function hasPermission(strCode) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理输入的命令中包含的\r符号
|
||||||
|
export function cleanCommand(text) {
|
||||||
|
return text ? text.replace(/\r\n/g, '\n') : ''
|
||||||
|
}
|
||||||
|
|
||||||
// 数组包含关系判断
|
// 数组包含关系判断
|
||||||
export function isSubArray(parent, child) {
|
export function isSubArray(parent, child) {
|
||||||
for (let item of child) {
|
for (let item of child) {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import 'ace-builds/src-noconflict/theme-tomorrow';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import http from 'libs/http';
|
import http from 'libs/http';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
|
import { cleanCommand } from "../../../libs";
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Ext1Setup3 extends React.Component {
|
class Ext1Setup3 extends React.Component {
|
||||||
|
@ -86,7 +87,7 @@ class Ext1Setup3 extends React.Component {
|
||||||
height={full === '1' ? '100vh' : '100px'}
|
height={full === '1' ? '100vh' : '100px'}
|
||||||
placeholder="每行一条规则"
|
placeholder="每行一条规则"
|
||||||
value={info['filter_rule']['data']}
|
value={info['filter_rule']['data']}
|
||||||
onChange={v => info['filter_rule']['data'] = v}
|
onChange={v => info['filter_rule']['data'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
@ -100,7 +101,7 @@ class Ext1Setup3 extends React.Component {
|
||||||
height={full === '3' ? '100vh' : '100px'}
|
height={full === '3' ? '100vh' : '100px'}
|
||||||
placeholder="输入要执行的命令"
|
placeholder="输入要执行的命令"
|
||||||
value={info['hook_pre_server']}
|
value={info['hook_pre_server']}
|
||||||
onChange={v => info['hook_pre_server'] = v}
|
onChange={v => info['hook_pre_server'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
@ -114,7 +115,7 @@ class Ext1Setup3 extends React.Component {
|
||||||
height={full === '5' ? '100vh' : '100px'}
|
height={full === '5' ? '100vh' : '100px'}
|
||||||
placeholder="输入要执行的命令"
|
placeholder="输入要执行的命令"
|
||||||
value={info['hook_pre_host']}
|
value={info['hook_pre_host']}
|
||||||
onChange={v => info['hook_pre_host'] = v}
|
onChange={v => info['hook_pre_host'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -144,7 +145,7 @@ class Ext1Setup3 extends React.Component {
|
||||||
height={full === '2' ? '100vh' : '100px'}
|
height={full === '2' ? '100vh' : '100px'}
|
||||||
placeholder="每行一个,例如:HOME=/data/spug"
|
placeholder="每行一个,例如:HOME=/data/spug"
|
||||||
value={info['custom_envs']}
|
value={info['custom_envs']}
|
||||||
onChange={v => info['custom_envs'] = v}
|
onChange={v => info['custom_envs'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
@ -158,7 +159,7 @@ class Ext1Setup3 extends React.Component {
|
||||||
height={full === '4' ? '100vh' : '100px'}
|
height={full === '4' ? '100vh' : '100px'}
|
||||||
placeholder="输入要执行的命令"
|
placeholder="输入要执行的命令"
|
||||||
value={info['hook_post_server']}
|
value={info['hook_post_server']}
|
||||||
onChange={v => info['hook_post_server'] = v}
|
onChange={v => info['hook_post_server'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
@ -172,7 +173,7 @@ class Ext1Setup3 extends React.Component {
|
||||||
height={full === '6' ? '100vh' : '100px'}
|
height={full === '6' ? '100vh' : '100px'}
|
||||||
placeholder="输入要执行的命令"
|
placeholder="输入要执行的命令"
|
||||||
value={info['hook_post_host']}
|
value={info['hook_post_host']}
|
||||||
onChange={v => info['hook_post_host'] = v}
|
onChange={v => info['hook_post_host'] = cleanCommand(v)}
|
||||||
style={{border: '1px solid #e8e8e8'}}/>
|
style={{border: '1px solid #e8e8e8'}}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Editor from 'react-ace';
|
||||||
import 'ace-builds/src-noconflict/mode-sh';
|
import 'ace-builds/src-noconflict/mode-sh';
|
||||||
import 'ace-builds/src-noconflict/theme-tomorrow';
|
import 'ace-builds/src-noconflict/theme-tomorrow';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
import http from 'libs/http';
|
import { http, cleanCommand } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
|
@ -51,7 +51,8 @@ class Ext2Setup3 extends React.Component {
|
||||||
style={{margin: '0 80px 20px'}}
|
style={{margin: '0 80px 20px'}}
|
||||||
description={[
|
description={[
|
||||||
<p key={1}>Spug 将遵循先本地后目标主机的原则,按照顺序依次执行添加的动作,例如:本地动作1 -> 本地动作2 -> 目标主机动作1 -> 目标主机动作2 ...</p>,
|
<p key={1}>Spug 将遵循先本地后目标主机的原则,按照顺序依次执行添加的动作,例如:本地动作1 -> 本地动作2 -> 目标主机动作1 -> 目标主机动作2 ...</p>,
|
||||||
<p key={2}>执行的命令内可以使用发布申请中设置的环境变量 SPUG_RELEASE,一般可用于标记一次发布的版本号或提交ID等,在执行的脚本内通过使用 $SPUG_RELEASE 获取其值来执行相应操作。</p>
|
<p key={2}>执行的命令内可以使用发布申请中设置的环境变量 SPUG_RELEASE,一般可用于标记一次发布的版本号或提交ID等,在执行的脚本内通过使用 $SPUG_RELEASE
|
||||||
|
获取其值来执行相应操作。</p>
|
||||||
]}/>
|
]}/>
|
||||||
)}
|
)}
|
||||||
{server_actions.map((item, index) => (
|
{server_actions.map((item, index) => (
|
||||||
|
@ -67,7 +68,7 @@ class Ext2Setup3 extends React.Component {
|
||||||
width="100%"
|
width="100%"
|
||||||
height="100px"
|
height="100px"
|
||||||
value={item['data']}
|
value={item['data']}
|
||||||
onChange={v => item['data'] = v}
|
onChange={v => item['data'] = cleanCommand(v)}
|
||||||
placeholder="请输入要执行的动作"/>
|
placeholder="请输入要执行的动作"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<div className={styles.delAction} onClick={() => server_actions.splice(index, 1)}>
|
<div className={styles.delAction} onClick={() => server_actions.splice(index, 1)}>
|
||||||
|
@ -94,7 +95,7 @@ class Ext2Setup3 extends React.Component {
|
||||||
width="100%"
|
width="100%"
|
||||||
height="100px"
|
height="100px"
|
||||||
value={item['data']}
|
value={item['data']}
|
||||||
onChange={v => item['data'] = v}
|
onChange={v => item['data'] = cleanCommand(v)}
|
||||||
placeholder="请输入要执行的动作"/>
|
placeholder="请输入要执行的动作"/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<div className={styles.delAction} onClick={() => host_actions.splice(index, 1)}>
|
<div className={styles.delAction} onClick={() => host_actions.splice(index, 1)}>
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { ACEditor, AuthCard } from 'components';
|
||||||
import HostSelector from './HostSelector';
|
import HostSelector from './HostSelector';
|
||||||
import TemplateSelector from './TemplateSelector';
|
import TemplateSelector from './TemplateSelector';
|
||||||
import ExecConsole from './ExecConsole';
|
import ExecConsole from './ExecConsole';
|
||||||
|
import { http, cleanCommand } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import http from 'libs/http';
|
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class TaskIndex extends React.Component {
|
class TaskIndex extends React.Component {
|
||||||
|
@ -26,7 +26,7 @@ class TaskIndex extends React.Component {
|
||||||
handleSubmit = () => {
|
handleSubmit = () => {
|
||||||
this.setState({loading: true});
|
this.setState({loading: true});
|
||||||
const host_ids = store.hosts.map(item => item.id);
|
const host_ids = store.hosts.map(item => item.id);
|
||||||
http.post('/api/exec/do/', {host_ids, command: this.state.body})
|
http.post('/api/exec/do/', {host_ids, command: cleanCommand(this.state.body)})
|
||||||
.then(store.switchConsole)
|
.then(store.switchConsole)
|
||||||
.finally(() => this.setState({loading: false}))
|
.finally(() => this.setState({loading: false}))
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Modal, Form, Input, Select, Col, Button, message } from 'antd';
|
import { Modal, Form, Input, Select, Col, Button, message } from 'antd';
|
||||||
import { ACEditor } from 'components';
|
import { ACEditor } from 'components';
|
||||||
import http from 'libs/http';
|
import { http, cleanCommand } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
|
@ -25,7 +25,7 @@ class ComForm extends React.Component {
|
||||||
this.setState({loading: true});
|
this.setState({loading: true});
|
||||||
const formData = this.props.form.getFieldsValue();
|
const formData = this.props.form.getFieldsValue();
|
||||||
formData['id'] = store.record.id;
|
formData['id'] = store.record.id;
|
||||||
formData['body'] = this.state.body;
|
formData['body'] = cleanCommand(this.state.body);
|
||||||
http.post('/api/exec/template/', formData)
|
http.post('/api/exec/template/', formData)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
message.success('操作成功');
|
message.success('操作成功');
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { observer } from 'mobx-react';
|
||||||
import { Modal, Form, Input, Select, Radio, message, Steps, Button, Transfer, Checkbox } from 'antd';
|
import { Modal, Form, Input, Select, Radio, message, Steps, Button, Transfer, Checkbox } from 'antd';
|
||||||
import TemplateSelector from '../exec/task/TemplateSelector';
|
import TemplateSelector from '../exec/task/TemplateSelector';
|
||||||
import { LinkButton, ACEditor } from 'components';
|
import { LinkButton, ACEditor } from 'components';
|
||||||
import http from 'libs/http';
|
import { http, cleanCommand } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import hostStore from '../host/store';
|
import hostStore from '../host/store';
|
||||||
import groupStore from '../alarm/group/store';
|
import groupStore from '../alarm/group/store';
|
||||||
|
@ -158,7 +158,7 @@ class ComForm extends React.Component {
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item required label="脚本内容" style={this.getStyle('4')}
|
<Form.Item required label="脚本内容" style={this.getStyle('4')}
|
||||||
extra={<LinkButton onClick={() => this.setState({showTmp: true})}>从模板添加</LinkButton>}>
|
extra={<LinkButton onClick={() => this.setState({showTmp: true})}>从模板添加</LinkButton>}>
|
||||||
<ACEditor mode="sh" value={extra['4']} height="200px" onChange={e => this.handleExtra('4', e)}/>
|
<ACEditor mode="sh" value={extra['4']} height="200px" onChange={e => this.handleExtra('4', cleanCommand(e))}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label="备注信息">
|
<Form.Item label="备注信息">
|
||||||
{getFieldDecorator('desc', {initialValue: info['desc']})(
|
{getFieldDecorator('desc', {initialValue: info['desc']})(
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { observer } from 'mobx-react';
|
||||||
import { Modal, Form, Input, Select, Col, Button, Steps, Tabs, InputNumber, DatePicker, Icon, message } from 'antd';
|
import { Modal, Form, Input, Select, Col, Button, Steps, Tabs, InputNumber, DatePicker, Icon, message } from 'antd';
|
||||||
import { LinkButton, ACEditor } from 'components';
|
import { LinkButton, ACEditor } from 'components';
|
||||||
import TemplateSelector from '../exec/task/TemplateSelector';
|
import TemplateSelector from '../exec/task/TemplateSelector';
|
||||||
import http from 'libs/http';
|
import { http, cleanCommand } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import hostStore from '../host/store';
|
import hostStore from '../host/store';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
|
@ -51,7 +51,7 @@ class ComForm extends React.Component {
|
||||||
}
|
}
|
||||||
this.setState({loading: true});
|
this.setState({loading: true});
|
||||||
formData['id'] = store.record.id;
|
formData['id'] = store.record.id;
|
||||||
formData['command'] = this.state.command;
|
formData['command'] = cleanCommand(this.state.command);
|
||||||
formData['targets'] = store.targets.filter(x => x);
|
formData['targets'] = store.targets.filter(x => x);
|
||||||
formData['trigger_args'] = this._parse_args(formData['trigger']);
|
formData['trigger_args'] = this._parse_args(formData['trigger']);
|
||||||
http.post('/api/schedule/', formData)
|
http.post('/api/schedule/', formData)
|
||||||
|
|
Loading…
Reference in New Issue