fix issue

pull/410/head
vapao 2021-08-17 16:28:02 +08:00
parent c078f9aa5d
commit 1897739512
5 changed files with 71 additions and 17 deletions

View File

@ -165,7 +165,7 @@ def _deploy_ext1_host(req, helper, h_id, env):
helper.send_error(host.id, f'检测到该主机的发布目录 {extend.dst_dir!r} 已存在为了数据安全请自行备份后删除该目录Spug 将会创建并接管该目录。') helper.send_error(host.id, f'检测到该主机的发布目录 {extend.dst_dir!r} 已存在为了数据安全请自行备份后删除该目录Spug 将会创建并接管该目录。')
# clean # clean
clean_command = f'ls -d {extend.deploy_id}_* 2> /dev/null | sort -t _ -rnk2 | tail -n +{extend.versions + 1} | xargs rm -rf' 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} && rm -rf {req.spug_version} && {clean_command}') helper.remote_raw(host.id, ssh, f'cd {extend.dst_repo} && {clean_command}')
# transfer files # transfer files
tar_gz_file = f'{req.spug_version}.tar.gz' tar_gz_file = f'{req.spug_version}.tar.gz'
try: try:
@ -173,7 +173,7 @@ def _deploy_ext1_host(req, helper, h_id, env):
except Exception as e: except Exception as e:
helper.send_error(host.id, f'exception: {e}') helper.send_error(host.id, f'exception: {e}')
command = f'cd {extend.dst_repo} && tar xf {tar_gz_file} && rm -f {req.deploy_id}_*.tar.gz' 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.remote_raw(host.id, ssh, command)
helper.send_step(h_id, 1, '完成\r\n') helper.send_step(h_id, 1, '完成\r\n')

View File

@ -7,5 +7,6 @@ from .views import *
urlpatterns = [ urlpatterns = [
path('', RepositoryView.as_view()), path('', RepositoryView.as_view()),
path('<int:r_id>/', get_detail),
path('request/', get_requests), path('request/', get_requests),
] ]

View File

@ -4,7 +4,8 @@
from django.views.generic import View from django.views.generic import View
from django.db.models import F from django.db.models import F
from django.conf import settings from django.conf import settings
from libs import json_response, JsonParser, Argument, AttrDict from django_redis import get_redis_connection
from libs import json_response, JsonParser, Argument, human_time, AttrDict
from apps.repository.models import Repository from apps.repository.models import Repository
from apps.deploy.models import DeployRequest from apps.deploy.models import DeployRequest
from apps.repository.utils import dispatch from apps.repository.utils import dispatch
@ -102,3 +103,32 @@ def get_requests(request):
data['status_alias'] = item.get_status_display() data['status_alias'] = item.get_status_display()
requests.append(data) requests.append(data)
return json_response(requests) return json_response(requests)
def get_detail(request, r_id):
repository = Repository.objects.filter(pk=r_id).first()
if not repository:
return json_response(error='未找到指定构建记录')
rds, counter = get_redis_connection(), 0
key = f'{settings.BUILD_KEY}:{repository.spug_version}'
data = rds.lrange(key, counter, counter + 9)
response = AttrDict(data='', step=0, s_status='process', status=repository.status)
while data:
for item in data:
counter += 1
item = json.loads(item.decode())
if 'data' in item:
response.data += item['data']
if 'step' in item:
response.step = item['step']
if 'status' in item:
response.status = item['status']
data = rds.lrange(key, counter, counter + 9)
response.index = counter
if repository.status in ('0', '1'):
response.data = f'{human_time()} 建立连接... ' + response.data
elif not response.data:
response.data = f'{human_time()} 读取数据... \r\n\r\n未读取到数据Spug 仅保存最近2周的构建日志。'
else:
response.data = f'{human_time()} 读取数据... ' + response.data
return json_response(response)

View File

@ -79,7 +79,10 @@ class AttrDict(dict):
self.__setitem__(key, value) self.__setitem__(key, value)
def __getattr__(self, item): def __getattr__(self, item):
try:
return self.__getitem__(item) return self.__getitem__(item)
except KeyError:
raise AttributeError(item)
def __delattr__(self, item): def __delattr__(self, item):
self.__delitem__(item) self.__delitem__(item)

View File

@ -8,21 +8,35 @@ import { observer } from 'mobx-react';
import { FullscreenOutlined, FullscreenExitOutlined, LoadingOutlined } from '@ant-design/icons'; import { FullscreenOutlined, FullscreenExitOutlined, LoadingOutlined } from '@ant-design/icons';
import { FitAddon } from 'xterm-addon-fit'; import { FitAddon } from 'xterm-addon-fit';
import { Terminal } from 'xterm'; import { Terminal } from 'xterm';
import { Modal, Steps } from 'antd'; import { Modal, Steps, Spin } from 'antd';
import { X_TOKEN, human_time } from 'libs'; import { X_TOKEN, http } from 'libs';
import styles from './index.module.less'; import styles from './index.module.less';
import store from './store'; import store from './store';
export default observer(function Console() { export default observer(function Console() {
const el = useRef() const el = useRef()
const [term] = useState(new Terminal({disableStdin: true}))
const [fullscreen, setFullscreen] = useState(false); const [fullscreen, setFullscreen] = useState(false);
const [step, setStep] = useState(0); const [step, setStep] = useState(0);
const [status, setStatus] = useState('process') const [status, setStatus] = useState('process');
const [fetching, setFetching] = useState(true);
useEffect(() => { useEffect(() => {
const term = initialTerm() let socket;
term.write(`${human_time()} 建立连接... `) initialTerm()
let index = 0; http.get(`/api/repository/${store.record.id}/`)
.then(res => {
term.write(res.data)
setStep(res.step)
setStatus(res.status)
socket = _makeSocket(res.index)
})
.finally(() => setFetching(false))
return () => socket && socket.close()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
function _makeSocket(index = 0) {
const token = store.record.spug_version; const token = store.record.spug_version;
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/build/${token}/?x-token=${X_TOKEN}`); const socket = new WebSocket(`${protocol}//${window.location.host}/api/ws/build/${token}/?x-token=${X_TOKEN}`);
@ -38,17 +52,21 @@ export default observer(function Console() {
if (status !== undefined) setStatus(status); if (status !== undefined) setStatus(status);
} }
} }
return () => socket.close(); return socket
}, []) }
useEffect(() => {
term.fit && term.fit()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fullscreen])
function initialTerm() { function initialTerm() {
const fitPlugin = new FitAddon() const fitPlugin = new FitAddon()
const term = new Terminal({disableStdin: true})
term.loadAddon(fitPlugin) term.loadAddon(fitPlugin)
term.setOption('theme', {background: '#fafafa', foreground: '#000', selection: '#999'}) term.setOption('theme', {background: '#fafafa', foreground: '#000', selection: '#999'})
term.open(el.current) term.open(el.current)
term.fit = () => fitPlugin.fit()
fitPlugin.fit() fitPlugin.fit()
return term
} }
function handleClose() { function handleClose() {
@ -85,9 +103,11 @@ export default observer(function Console() {
<StepItem title="检出后任务" step={3}/> <StepItem title="检出后任务" step={3}/>
<StepItem title="执行打包" step={4}/> <StepItem title="执行打包" step={4}/>
</Steps> </Steps>
<Spin spinning={fetching}>
<div className={styles.out}> <div className={styles.out}>
<div ref={el}/> <div ref={el}/>
</div> </div>
</Spin>
</Modal> </Modal>
) )
}) })