mirror of https://github.com/openspug/spug
F 修复发布日志可能记录不完整的问题
parent
5e15e348a1
commit
bebd5277ee
|
@ -21,7 +21,7 @@ def deploy_dispatch(request, req, token):
|
|||
try:
|
||||
api_token = uuid.uuid4().hex
|
||||
rds.setex(api_token, 60 * 60, f'{req.deploy.app_id},{req.deploy.env_id}')
|
||||
helper = Helper(rds, token)
|
||||
helper = Helper(rds, token, req.id)
|
||||
helper.send_step('local', 1, f'完成\r\n{human_time()} 发布准备... ')
|
||||
env = AttrDict(
|
||||
SPUG_APP_NAME=req.deploy.app.name,
|
||||
|
@ -177,9 +177,11 @@ def _deploy_ext2_host(helper, h_id, actions, env):
|
|||
|
||||
|
||||
class Helper:
|
||||
def __init__(self, rds, token):
|
||||
def __init__(self, rds, token, r_id):
|
||||
self.rds = rds
|
||||
self.token = token
|
||||
self.log_key = f'{settings.REQUEST_KEY}:{r_id}'
|
||||
self.rds.delete(self.log_key)
|
||||
|
||||
@staticmethod
|
||||
def send_deploy_notify(req):
|
||||
|
@ -235,16 +237,20 @@ class Helper:
|
|||
files.append(line)
|
||||
return files
|
||||
|
||||
def _send(self, message):
|
||||
self.rds.lpush(self.token, json.dumps(message))
|
||||
self.rds.lpush(self.log_key, json.dumps(message))
|
||||
|
||||
def send_info(self, key, message):
|
||||
self.rds.lpush(self.token, json.dumps({'key': key, 'status': 'info', 'data': message}))
|
||||
self._send({'key': key, 'status': 'info', 'data': message})
|
||||
|
||||
def send_error(self, key, message):
|
||||
message = '\r\n' + message
|
||||
self.rds.lpush(self.token, json.dumps({'key': key, 'status': 'error', 'data': message}))
|
||||
self._send({'key': key, 'status': 'error', 'data': message})
|
||||
raise Exception(message)
|
||||
|
||||
def send_step(self, key, step, data):
|
||||
self.rds.lpush(self.token, json.dumps({'key': key, 'step': step, 'data': data}))
|
||||
self._send({'key': key, 'step': step, 'data': data})
|
||||
|
||||
def local(self, command, env=None):
|
||||
command = 'set -e\n' + command
|
||||
|
|
|
@ -3,24 +3,17 @@
|
|||
# Released under the MIT License.
|
||||
from channels.generic.websocket import WebsocketConsumer
|
||||
from django_redis import get_redis_connection
|
||||
from django.conf import settings
|
||||
from apps.setting.utils import AppSetting
|
||||
from apps.host.models import Host
|
||||
from threading import Thread
|
||||
from urllib.parse import parse_qs
|
||||
import json
|
||||
|
||||
|
||||
class ExecConsumer(WebsocketConsumer):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
query = parse_qs(self.scope['query_string'].decode())
|
||||
e_id = query.get('id', [None])[0]
|
||||
self.token = self.scope['url_route']['kwargs']['token']
|
||||
self.log_key = f'{settings.REQUEST_KEY}:{e_id}' if e_id else None
|
||||
self.rds = get_redis_connection()
|
||||
if self.log_key:
|
||||
self.rds.delete(self.log_key)
|
||||
|
||||
def connect(self):
|
||||
self.accept()
|
||||
|
@ -29,11 +22,8 @@ class ExecConsumer(WebsocketConsumer):
|
|||
self.rds.close()
|
||||
|
||||
def get_response(self):
|
||||
if self.log_key:
|
||||
return self.rds.brpoplpush(self.token, self.log_key, timeout=5)
|
||||
else:
|
||||
response = self.rds.brpop(self.token, timeout=5)
|
||||
return response[1] if response else None
|
||||
response = self.rds.brpop(self.token, timeout=5)
|
||||
return response[1] if response else None
|
||||
|
||||
def receive(self, **kwargs):
|
||||
response = self.get_response()
|
||||
|
|
|
@ -17,6 +17,8 @@ import lds from 'lodash';
|
|||
class Ext1Index extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.id = props.match.params.id;
|
||||
this.log = props.match.params.log;
|
||||
this.state = {
|
||||
fetching: true,
|
||||
loading: false,
|
||||
|
@ -25,11 +27,21 @@ class Ext1Index extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.id = this.props.match.params.id;
|
||||
this.log = this.props.match.params.log;
|
||||
this.fetch()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.socket) this.socket.close();
|
||||
store.request = {targets: [], host_actions: [], server_actions: []};
|
||||
store.outputs = {};
|
||||
}
|
||||
|
||||
fetch = () => {
|
||||
this.setState({fetching: true});
|
||||
http.get(`/api/deploy/request/${this.id}/`, {params: {log: this.log}})
|
||||
.then(res => {
|
||||
store.request = res;
|
||||
store.outputs = {};
|
||||
while (res.outputs.length) {
|
||||
const msg = JSON.parse(res.outputs.pop());
|
||||
if (!store.outputs.hasOwnProperty(msg.key)) {
|
||||
|
@ -40,13 +52,7 @@ class Ext1Index extends React.Component {
|
|||
}
|
||||
})
|
||||
.finally(() => this.setState({fetching: false}))
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.socket) this.socket.close();
|
||||
store.request = {targets: [], host_actions: [], server_actions: []};
|
||||
store.outputs = {};
|
||||
}
|
||||
};
|
||||
|
||||
_parse_message = (message) => {
|
||||
const {key, data, step, status} = message;
|
||||
|
@ -62,7 +68,7 @@ class Ext1Index extends React.Component {
|
|||
store.request.status = '2';
|
||||
store.outputs = outputs;
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
this.socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/exec/${token}/?id=${this.id}`);
|
||||
this.socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/exec/${token}/`);
|
||||
this.socket.onopen = () => {
|
||||
this.socket.send('ok');
|
||||
};
|
||||
|
@ -115,9 +121,13 @@ class Ext1Index extends React.Component {
|
|||
subTitle={`${app_name} - ${env_name}`}
|
||||
style={{padding: 0}}
|
||||
tags={this.getStatusAlias()}
|
||||
extra={<Button loading={this.state.loading} type="primary"
|
||||
disabled={this.log || !['1', '-3'].includes(status)}
|
||||
onClick={this.handleDeploy}>发布</Button>}
|
||||
extra={this.log ? (
|
||||
<Button icon="sync" type="primary" onClick={this.fetch}>刷新</Button>
|
||||
) : (
|
||||
<Button icon="play-circle" loading={this.state.loading} type="primary"
|
||||
disabled={!['1', '-3'].includes(status)}
|
||||
onClick={this.handleDeploy}>发布</Button>
|
||||
)}
|
||||
onBack={() => history.goBack()}/>
|
||||
<Collapse defaultActiveKey={1} className={styles.collapse}>
|
||||
<Collapse.Panel showArrow={false} key={1} header={
|
||||
|
|
|
@ -17,6 +17,8 @@ import lds from 'lodash';
|
|||
class Ext1Index extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.id = props.match.params.id;
|
||||
this.log = props.match.params.log;
|
||||
this.state = {
|
||||
fetching: true,
|
||||
loading: false,
|
||||
|
@ -25,11 +27,22 @@ class Ext1Index extends React.Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.id = this.props.match.params.id;
|
||||
this.log = this.props.match.params.log;
|
||||
this.fetch()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.socket) this.socket.close();
|
||||
store.request = {targets: [], server_actions: [], host_actions: []};
|
||||
store.outputs = {};
|
||||
}
|
||||
|
||||
|
||||
fetch = () => {
|
||||
this.setState({fetching: true});
|
||||
http.get(`/api/deploy/request/${this.id}/`, {params: {log: this.log}})
|
||||
.then(res => {
|
||||
store.request = res;
|
||||
store.outputs = {};
|
||||
while (res.outputs.length) {
|
||||
const msg = JSON.parse(res.outputs.pop());
|
||||
if (!store.outputs.hasOwnProperty(msg.key)) {
|
||||
|
@ -40,13 +53,7 @@ class Ext1Index extends React.Component {
|
|||
}
|
||||
})
|
||||
.finally(() => this.setState({fetching: false}))
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.socket) this.socket.close();
|
||||
store.request = {targets: [], server_actions: [], host_actions: []};
|
||||
store.outputs = {};
|
||||
}
|
||||
};
|
||||
|
||||
_parse_message = (message) => {
|
||||
const {key, data, step, status} = message;
|
||||
|
@ -62,7 +69,7 @@ class Ext1Index extends React.Component {
|
|||
store.request.status = '2';
|
||||
store.outputs = outputs;
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
this.socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/exec/${token}/?id=${this.id}`);
|
||||
this.socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/exec/${token}/`);
|
||||
this.socket.onopen = () => {
|
||||
this.socket.send('ok');
|
||||
};
|
||||
|
@ -115,8 +122,13 @@ class Ext1Index extends React.Component {
|
|||
subTitle={`${app_name} - ${env_name}`}
|
||||
style={{padding: 0}}
|
||||
tags={this.getStatusAlias()}
|
||||
extra={<Button loading={this.state.loading} type="primary" disabled={this.log || !['1', '-3'].includes(status)}
|
||||
onClick={this.handleDeploy}>发布</Button>}
|
||||
extra={this.log ? (
|
||||
<Button icon="sync" type="primary" onClick={this.fetch}>刷新</Button>
|
||||
) : (
|
||||
<Button icon="play-circle" loading={this.state.loading} type="primary"
|
||||
disabled={!['1', '-3'].includes(status)}
|
||||
onClick={this.handleDeploy}>发布</Button>
|
||||
)}
|
||||
onBack={() => history.goBack()}/>
|
||||
<Collapse defaultActiveKey={1} className={styles.collapse}>
|
||||
<Collapse.Panel showArrow={false} key={1} header={
|
||||
|
|
Loading…
Reference in New Issue