mirror of https://github.com/openspug/spug
A 发布配置路径和过滤规则支持使用全局变量
parent
348de8c36b
commit
95952f9348
|
@ -1,9 +1,7 @@
|
|||
# Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||
# Copyright: (c) <spug.dev@gmail.com>
|
||||
# Released under the AGPL-3.0 License.
|
||||
from django_redis import get_redis_connection
|
||||
from django.conf import settings
|
||||
from libs.utils import human_datetime
|
||||
from libs.utils import human_datetime, render_str
|
||||
from libs.spug import Notification
|
||||
from apps.host.models import Host
|
||||
import subprocess
|
||||
|
@ -208,13 +206,13 @@ class Helper:
|
|||
def add_callback(self, 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(), []
|
||||
if data:
|
||||
for line in data.split(sep):
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#'):
|
||||
files.append(line)
|
||||
files.append(render_str(line, env))
|
||||
return files
|
||||
|
||||
def _send(self, message):
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
from django_redis import get_redis_connection
|
||||
from django.conf import settings
|
||||
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.config.utils import compose_configs
|
||||
from apps.repository.models import Repository
|
||||
|
@ -74,8 +74,6 @@ def _ext1_deploy(req, helper, env):
|
|||
)
|
||||
build_repository(rep, helper)
|
||||
req.repository = rep
|
||||
extend = req.deploy.extend_obj
|
||||
env.update(SPUG_DST_DIR=extend.dst_dir)
|
||||
extras = json.loads(req.extra)
|
||||
if extras[0] == 'repository':
|
||||
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.local(f'cd /tmp && {action["data"]}', env)
|
||||
step += 1
|
||||
helper.send_step('local', 100, '')
|
||||
|
||||
for action in host_actions:
|
||||
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':
|
||||
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['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"]}')
|
||||
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']), ''
|
||||
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'], ',')
|
||||
files = helper.parse_filter_rule(action['rule'], ',', env)
|
||||
if files:
|
||||
if action['mode'] == '1':
|
||||
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.add_callback(partial(os.remove, os.path.join(sp_dir, tar_gz_file)))
|
||||
break
|
||||
helper.send_step('local', 100, '')
|
||||
|
||||
if host_actions:
|
||||
if req.deploy.is_parallel:
|
||||
threads, latest_exception = [], None
|
||||
|
@ -194,12 +197,15 @@ def _ext2_deploy(req, helper, 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()} 数据准备... ')
|
||||
host = Host.objects.filter(pk=h_id).first()
|
||||
if not host:
|
||||
helper.send_error(h_id, 'no such host')
|
||||
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:
|
||||
base_dst_dir = os.path.dirname(extend.dst_dir)
|
||||
code, _ = ssh.exec_command_raw(
|
||||
|
|
|
@ -159,12 +159,14 @@ class RequestDetailView(View):
|
|||
outputs['local'] = {'id': 'local', 'step': 0, 'data': f'{human_time()} 建立连接... '}
|
||||
if req.deploy.extend == '2':
|
||||
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)
|
||||
h_actions = json.loads(req.deploy.extend_obj.host_actions)
|
||||
if not h_actions:
|
||||
outputs = {'local': outputs['local']}
|
||||
return json_response({'s_actions': s_actions, 'h_actions': h_actions, 'outputs': outputs})
|
||||
s_actions = json.loads(req.deploy.extend_obj.server_actions)
|
||||
h_actions = json.loads(req.deploy.extend_obj.host_actions)
|
||||
for item in h_actions:
|
||||
if item.get('type') == 'transfer' and item.get('src_mode') == '0':
|
||||
s_actions.append({'title': '执行打包'})
|
||||
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})
|
||||
|
||||
@auth('deploy.request.approve')
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
from django_redis import get_redis_connection
|
||||
from django.conf import settings
|
||||
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.app.utils import fetch_repo
|
||||
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))
|
||||
build_dir = os.path.join(REPOS_DIR, rep.spug_version)
|
||||
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':
|
||||
tree_ish = extras[2]
|
||||
env.update(SPUG_GIT_BRANCH=extras[1], SPUG_GIT_COMMIT_ID=extras[2])
|
||||
else:
|
||||
tree_ish = 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)
|
||||
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()} 执行打包... ')
|
||||
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 filter_rule['type'] == 'exclude':
|
||||
excludes = []
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.http.response import HttpResponse
|
|||
from django.db.models import QuerySet
|
||||
from datetime import datetime, date as datetime_date
|
||||
from decimal import Decimal
|
||||
from string import Template
|
||||
import string
|
||||
import random
|
||||
import json
|
||||
|
@ -62,6 +63,11 @@ def human_diff_time(time1, time2):
|
|||
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=''):
|
||||
content = AttrDict(data=data, error=error)
|
||||
if error:
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
}
|
||||
|
||||
.header {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
@ -90,12 +91,6 @@
|
|||
font-size: 22px;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 22px;
|
||||
font-weight: 300;
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue