A 发布配置路径和过滤规则支持使用全局变量

pull/442/head
vapao 2021-12-21 10:12:31 +08:00
parent 348de8c36b
commit 95952f9348
6 changed files with 35 additions and 28 deletions

View File

@ -1,9 +1,7 @@
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
# Copyright: (c) <spug.dev@gmail.com> # Copyright: (c) <spug.dev@gmail.com>
# Released under the AGPL-3.0 License. # Released under the AGPL-3.0 License.
from django_redis import get_redis_connection from libs.utils import human_datetime, render_str
from django.conf import settings
from libs.utils import human_datetime
from libs.spug import Notification from libs.spug import Notification
from apps.host.models import Host from apps.host.models import Host
import subprocess import subprocess
@ -208,13 +206,13 @@ class Helper:
def add_callback(self, func): def add_callback(self, func):
self.callback.append(func) self.callback.append(func)
def parse_filter_rule(self, data: str, sep='\n'): def parse_filter_rule(self, data: str, sep='\n', env=None):
data, files = data.strip(), [] data, files = data.strip(), []
if data: if data:
for line in data.split(sep): for line in data.split(sep):
line = line.strip() line = line.strip()
if line and not line.startswith('#'): if line and not line.startswith('#'):
files.append(line) files.append(render_str(line, env))
return files return files
def _send(self, message): def _send(self, message):

View File

@ -4,7 +4,7 @@
from django_redis import get_redis_connection from django_redis import get_redis_connection
from django.conf import settings from django.conf import settings
from django.db import close_old_connections from django.db import close_old_connections
from libs.utils import AttrDict, human_time from libs.utils import AttrDict, human_time, render_str
from apps.host.models import Host from apps.host.models import Host
from apps.config.utils import compose_configs from apps.config.utils import compose_configs
from apps.repository.models import Repository from apps.repository.models import Repository
@ -74,8 +74,6 @@ def _ext1_deploy(req, helper, env):
) )
build_repository(rep, helper) build_repository(rep, helper)
req.repository = rep req.repository = rep
extend = req.deploy.extend_obj
env.update(SPUG_DST_DIR=extend.dst_dir)
extras = json.loads(req.extra) extras = json.loads(req.extra)
if extras[0] == 'repository': if extras[0] == 'repository':
extras = extras[1:] extras = extras[1:]
@ -127,22 +125,25 @@ def _ext2_deploy(req, helper, env):
helper.send_step('local', step, f'{human_time()} {action["title"]}...\r\n') helper.send_step('local', step, f'{human_time()} {action["title"]}...\r\n')
helper.local(f'cd /tmp && {action["data"]}', env) helper.local(f'cd /tmp && {action["data"]}', env)
step += 1 step += 1
helper.send_step('local', 100, '')
for action in host_actions: for action in host_actions:
if action.get('type') == 'transfer': if action.get('type') == 'transfer':
action['src'] = render_str(action['src'].strip().rstrip('/'), env)
action['dst'] = render_str(action['dst'].strip().rstrip('/'), env)
if action.get('src_mode') == '1': if action.get('src_mode') == '1':
break break
helper.send_info('local', f'{human_time()} 检测到来源为本地路径的数据传输动作,执行打包... \r\n') helper.send_step('local', step, f'{human_time()} 检测到来源为本地路径的数据传输动作,执行打包... \r\n')
action['src'] = action['src'].rstrip('/ ') action['src'] = action['src'].rstrip('/ ')
action['dst'] = action['dst'].rstrip('/ ') action['dst'] = action['dst'].rstrip('/ ')
if not action['src'] or not action['dst']: if not action['src'] or not action['dst']:
helper.send_error('local', f'invalid path for transfer, src: {action["src"]} dst: {action["dst"]}') helper.send_error('local', f'Invalid path for transfer, src: {action["src"]} dst: {action["dst"]}')
if not os.path.exists(action['src']):
helper.send_error('local', f'No such file or directory: {action["src"]}')
is_dir, exclude = os.path.isdir(action['src']), '' is_dir, exclude = os.path.isdir(action['src']), ''
sp_dir, sd_dst = os.path.split(action['src']) sp_dir, sd_dst = os.path.split(action['src'])
contain = sd_dst contain = sd_dst
if action['mode'] != '0' and is_dir: if action['mode'] != '0' and is_dir:
files = helper.parse_filter_rule(action['rule'], ',') files = helper.parse_filter_rule(action['rule'], ',', env)
if files: if files:
if action['mode'] == '1': if action['mode'] == '1':
contain = ' '.join(f'{sd_dst}/{x}' for x in files) contain = ' '.join(f'{sd_dst}/{x}' for x in files)
@ -159,6 +160,8 @@ def _ext2_deploy(req, helper, env):
helper.send_info('local', f'{human_time()} \033[32m完成√\033[0m\r\n') helper.send_info('local', f'{human_time()} \033[32m完成√\033[0m\r\n')
helper.add_callback(partial(os.remove, os.path.join(sp_dir, tar_gz_file))) helper.add_callback(partial(os.remove, os.path.join(sp_dir, tar_gz_file)))
break break
helper.send_step('local', 100, '')
if host_actions: if host_actions:
if req.deploy.is_parallel: if req.deploy.is_parallel:
threads, latest_exception = [], None threads, latest_exception = [], None
@ -194,12 +197,15 @@ def _ext2_deploy(req, helper, env):
def _deploy_ext1_host(req, helper, h_id, env): def _deploy_ext1_host(req, helper, h_id, env):
extend = req.deploy.extend_obj
helper.send_step(h_id, 1, f'\033[32m就绪√\033[0m\r\n{human_time()} 数据准备... ') helper.send_step(h_id, 1, f'\033[32m就绪√\033[0m\r\n{human_time()} 数据准备... ')
host = Host.objects.filter(pk=h_id).first() host = Host.objects.filter(pk=h_id).first()
if not host: if not host:
helper.send_error(h_id, 'no such host') helper.send_error(h_id, 'no such host')
env.update({'SPUG_HOST_ID': h_id, 'SPUG_HOST_NAME': host.hostname}) env.update({'SPUG_HOST_ID': h_id, 'SPUG_HOST_NAME': host.hostname})
extend = req.deploy.extend_obj
extend.dst_dir = render_str(extend.dst_dir, env)
extend.dst_repo = render_str(extend.dst_repo, env)
env.update(SPUG_DST_DIR=extend.dst_dir)
with host.get_ssh(default_env=env) as ssh: with host.get_ssh(default_env=env) as ssh:
base_dst_dir = os.path.dirname(extend.dst_dir) base_dst_dir = os.path.dirname(extend.dst_dir)
code, _ = ssh.exec_command_raw( code, _ = ssh.exec_command_raw(

View File

@ -159,12 +159,14 @@ class RequestDetailView(View):
outputs['local'] = {'id': 'local', 'step': 0, 'data': f'{human_time()} 建立连接... '} outputs['local'] = {'id': 'local', 'step': 0, 'data': f'{human_time()} 建立连接... '}
if req.deploy.extend == '2': if req.deploy.extend == '2':
outputs['local'] = {'id': 'local', 'step': 0, 'data': f'{human_time()} 建立连接... '} outputs['local'] = {'id': 'local', 'step': 0, 'data': f'{human_time()} 建立连接... '}
if req.deploy.extend == '2': s_actions = json.loads(req.deploy.extend_obj.server_actions)
s_actions = json.loads(req.deploy.extend_obj.server_actions) h_actions = json.loads(req.deploy.extend_obj.host_actions)
h_actions = json.loads(req.deploy.extend_obj.host_actions) for item in h_actions:
if not h_actions: if item.get('type') == 'transfer' and item.get('src_mode') == '0':
outputs = {'local': outputs['local']} s_actions.append({'title': '执行打包'})
return json_response({'s_actions': s_actions, 'h_actions': h_actions, 'outputs': outputs}) if not h_actions:
outputs = {'local': outputs['local']}
return json_response({'s_actions': s_actions, 'h_actions': h_actions, 'outputs': outputs})
return json_response({'outputs': outputs}) return json_response({'outputs': outputs})
@auth('deploy.request.approve') @auth('deploy.request.approve')

View File

@ -4,7 +4,7 @@
from django_redis import get_redis_connection from django_redis import get_redis_connection
from django.conf import settings from django.conf import settings
from django.db import close_old_connections from django.db import close_old_connections
from libs.utils import AttrDict, human_time from libs.utils import AttrDict, human_time, render_str
from apps.repository.models import Repository from apps.repository.models import Repository
from apps.app.utils import fetch_repo from apps.app.utils import fetch_repo
from apps.config.utils import compose_configs from apps.config.utils import compose_configs
@ -68,13 +68,13 @@ def _build(rep: Repository, helper, env):
git_dir = os.path.join(REPOS_DIR, str(rep.deploy_id)) git_dir = os.path.join(REPOS_DIR, str(rep.deploy_id))
build_dir = os.path.join(REPOS_DIR, rep.spug_version) build_dir = os.path.join(REPOS_DIR, rep.spug_version)
tar_file = os.path.join(BUILD_DIR, f'{rep.spug_version}.tar.gz') tar_file = os.path.join(BUILD_DIR, f'{rep.spug_version}.tar.gz')
env.update(SPUG_DST_DIR=extend.dst_dir)
if extras[0] == 'branch': if extras[0] == 'branch':
tree_ish = extras[2] tree_ish = extras[2]
env.update(SPUG_GIT_BRANCH=extras[1], SPUG_GIT_COMMIT_ID=extras[2]) env.update(SPUG_GIT_BRANCH=extras[1], SPUG_GIT_COMMIT_ID=extras[2])
else: else:
tree_ish = extras[1] tree_ish = extras[1]
env.update(SPUG_GIT_TAG=extras[1]) env.update(SPUG_GIT_TAG=extras[1])
env.update(SPUG_DST_DIR=render_str(extend.dst_dir, env))
fetch_repo(rep.deploy_id, extend.git_repo) fetch_repo(rep.deploy_id, extend.git_repo)
helper.send_info('local', '\033[32m完成√\033[0m\r\n') helper.send_info('local', '\033[32m完成√\033[0m\r\n')
@ -93,7 +93,7 @@ def _build(rep: Repository, helper, env):
helper.send_step('local', 4, f'\r\n{human_time()} 执行打包... ') helper.send_step('local', 4, f'\r\n{human_time()} 执行打包... ')
filter_rule, exclude, contain = json.loads(extend.filter_rule), '', rep.spug_version filter_rule, exclude, contain = json.loads(extend.filter_rule), '', rep.spug_version
files = helper.parse_filter_rule(filter_rule['data']) files = helper.parse_filter_rule(filter_rule['data'], env=env)
if files: if files:
if filter_rule['type'] == 'exclude': if filter_rule['type'] == 'exclude':
excludes = [] excludes = []

View File

@ -5,6 +5,7 @@ from django.http.response import HttpResponse
from django.db.models import QuerySet from django.db.models import QuerySet
from datetime import datetime, date as datetime_date from datetime import datetime, date as datetime_date
from decimal import Decimal from decimal import Decimal
from string import Template
import string import string
import random import random
import json import json
@ -62,6 +63,11 @@ def human_diff_time(time1, time2):
return '%d%s' % (delta.days, text) if delta.days else text return '%d%s' % (delta.days, text) if delta.days else text
# 字符串模版渲染
def render_str(template, datasheet):
return Template(template).safe_substitute(datasheet)
def json_response(data='', error=''): def json_response(data='', error=''):
content = AttrDict(data=data, error=error) content = AttrDict(data=data, error=error)
if error: if error:

View File

@ -69,6 +69,7 @@
} }
.header { .header {
flex: 1;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@ -90,12 +91,6 @@
font-size: 22px; font-size: 22px;
color: #1890ff; color: #1890ff;
} }
.icon {
font-size: 22px;
font-weight: 300;
color: #1890ff;
}
} }
} }