代码拉取完成,页面将自动刷新
同步操作将从 wei2011/Dkit 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
# -*- coding: utf-8 -*-
"""
Created on Mon Dec 15 15:29:27 2014
@author: wei
"""
from app import db
from app.models import *
import paramiko
from utils import log
import os
import sys
import re
import time
from imp import reload
import logging
from datetime import date
logger=log.get_logger('update',__name__)
__logging_date=date.today()
def reload_logger():
global logger
global __logging_date
if __logging_date==date.today():#如果是当天的就不用重新加载logging了
return
__logging_date=date.today()
logging.shutdown()
reload(logging)
logger=log.get_logger('update',__name__)
update_cmds_temp='''
export LANG="{lang}"
if [ ! -d "{branch_path_svn}" ]; then
mkdir -p {branch_path};
svn checkout {branch_svn_url} {branch_path} --force --no-auth-cache --username {svn_username} --password {svn_password}
cd {branch_path}
{init_cmds}
else
svn revert -R {branch_path}
svn update {branch_path} --no-auth-cache --username {svn_username} --password {svn_password}
fi
cd {branch_path}
{other_cmds}
'''
def get_ssh(host,port=22,username='root',password=''):
ssh=paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try :
ssh.connect(host,port,username,password)
return ssh,''
except Exception as e:
return None,str(e)
def _get_remote_server_lang(ssh,sleepfunc):
chan=ssh.invoke_shell()
try:
chan.send('locale\n')
result=''
try_time=0
while True:
sleepfunc(1)
rs=chan.recv(1000).decode()
d=dict(re.findall('(.+)=(.+)\r',rs))
result=d.get('LANG')
if result or try_time>5:
break
try_time+=1
return result
finally:
chan.close()
def _deploy_stat(func):
def update_status(dinfo,sleepfunc):
try:
update=db.update(Deploy_info).values(
is_deploying =True,
deploytime =db.func.now()
).where(Deploy_info.id==dinfo.id)
db.session.execute(update)
db.session.commit()
func(dinfo,sleepfunc)
finally:
update=db.update(Deploy_info).values(
is_deploying =False
).where(Deploy_info.id==dinfo.id)
db.session.execute(update)
db.session.commit()
return update_status
def _handle_log(reader,decoding,write_log,sleepfunc):
r=b''
buf=reader.read(500)
while buf:
n=0
l=len(buf)
for i in range(l):
if buf[i]==10:#\n 回车符
temp=r+buf[n:i]
write_log(temp.decode(decoding).strip('\r'))
r=b''
n=i+1
sleepfunc(0.02)
if l==(i+1):
r+=buf[n:]
buf=reader.read(500)
sleepfunc(0.02)
if r:
write_log(r.decode(decoding).strip('\r'))
#def exec_command(self, command, bufsize=-1,timeout = None):
# chan = self._transport.open_session()
# if timeout is not None:
# chan.settimeout(timeout)
# chan.exec_command(command)
# stdin = chan.makefile('wb', bufsize)
# stdout = chan.makefile('rb', bufsize)
# stderr = chan.makefile_stderr('rb', bufsize)
# return stdin, stdout, stderr
@_deploy_stat
def deploy_branch(dinfo,sleepfunc):
if not dinfo.server_ids:
raise Exception('分枝[%s]未设置部署服务器!' % dinfo.branch)
svn_username=Configs.get_value('SVN_USERNAME')
svn_password=Configs.get_value('SVN_PASSWORD')
repos_name=dinfo.repository_name
repos_svn_url=os.path.join(Configs.get_value('SVN_URL'),repos_name)#仓库SVN路径
branch_svn_url=os.path.join(repos_svn_url,dinfo.branch) if dinfo.branch!='/' else repos_svn_url
#部署地址
branch_path=dinfo.deploy_path.replace('<repos>',repos_name).replace('<branch>',dinfo.branch if dinfo.branch!='/' else '')
branch_path_svn=os.path.join(branch_path,'.svn')#通过SVN目录判断
servers=Servers.query.filter(Servers.id.in_(dinfo.server_ids.split(',')))
for svr in servers:
ssh,err=get_ssh(svr.host,svr.port,svr.user,svr.pwd)
if not ssh:
logger.error('无法连接到服务器[%s]:%s' % (svr.host,err))
continue
lang=_get_remote_server_lang(ssh,sleepfunc)
if not lang:
logger.error('无法取得服务器[%s]的语言/编码设置!' % svr.host)
continue
decoding=lang.split('.')[1]
update_cmds=update_cmds_temp.format(
lang=lang,
branch_path_svn=branch_path_svn,
branch_path=branch_path,
branch_svn_url=branch_svn_url,
svn_username=svn_username,
svn_password=svn_password,
init_cmds=dinfo.init_cmds.replace('\r','') or '',
other_cmds=dinfo.cmds.replace('\r','') or ''
)
#保存本次执行的更新命令
#last_exec_cmds_file=os.path.join(os.path.abspath(os.path.dirname(__file__)),'last_exec_cmds.txt')
#with open(last_exec_cmds_file,'w') as f:
# f.write(update_cmds)
logger.info('更新服务器[%s] %s >>>' % (svr.host,dinfo.deploy_path) )
try:
stdin,stdout,stderr=ssh.exec_command(update_cmds)
sleepfunc(1)
_handle_log(stdout,decoding,logger.info,sleepfunc)
_handle_log(stderr,decoding,logger.error,sleepfunc)
finally:
stdin.close()
stdout.close()
stderr.close()
ssh.close()
def _check_branch_in_list(branch,changed_list):
if branch=='/':
return True
result=False
for _,changed_file in changed_list:
if changed_file.startswith(branch):
result=True
break
return result
def _run_cmd(cmd):
f=os.popen(cmd)
try:
result=f.read()
finally:
f.close()
return result
def _do_deploy(repos,version=None):#用update部署
#取得svn更新文件列表
if version:
cmd='svnlook changed -r %s %s' % (version,repos)
else:
cmd='svnlook changed %s' % repos#最近更新
r=_run_cmd(cmd)
l=r.split('\n')
changed_list=[re.split(' +',r,1) for r in l if r]
if not changed_list:
logger.info('没有更新的内容!')
return
repos_list=Repository.query.all()
deployed=False
for rep in repos_list:
if repos.startswith(rep.location):
for deploy_info in rep.deploy_infos:
if _check_branch_in_list(deploy_info.branch,changed_list):#判断分枝是否有更新
try:
deployed=True
logger.info('分枝:%s' % deploy_info.branch)
deploy_branch(deploy_info,time.sleep)
except Exception as e:
logger.error('部署[%s]出错:%s' % (rep.name,str(e)))
if not deployed:
logger.info('没有部署的分枝!')
if __name__=='__main__':
if len(sys.argv)==3:
repos,version=sys.argv[1],sys.argv[2]
repos_name=repos[repos.rfind('/')+1:]#仓库名
#取得修改作者
cmd='svnlook author -r %s %s' % (version,repos)
r=_run_cmd(cmd)
author=r.rstrip('\n').replace('\n',',')
logger.info('***********************************************')
logger.info('更新部署:%s 版本号:%s 修改作者:%s' % (repos_name,version,author))
try:
_do_deploy(repos,version)
except Exception as e:
logger.error('部署出错:%s' % str(e))
else:
logger.info('部署参数错误:%s' % repr(sys.argv))
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。