您的位置:首页 > 运维架构 > 网站架构

自动化运维:网站svn代码上线更新(flask+saltstack)

2016-08-09 15:26 197 查看

阶段性总结:

跌跌撞撞的用了一周左右的时间做完了网站自动升级功能,中间遇到了很多的问题,也学到了很多,在此做一个总结。

1、整体架构:

后台:nginx+uwsgi #nginx提供web服务,uwsgi对python代码进行解析
前台:flask+bootstrap+html #flask是python的一套web开发工具,bootstrap是一套现成的模板,html不用解释。
功能:shell+saltstack+svn #saltstack 功能的核心,自动化运维工具。 shell 不解释,svn代码一致性工具。

2、用到的技巧:

python相关:

对于文件的读写
列表的相关操作
字典的调用
如何执行shell命令
时间模块
线程的使用

flask相关:

表单
session
flash
其他的貌似想不到了,注释代码的时候一并回忆整理吧。

3、下面进行代码的review和注释

########################################################################################
########################################################################################
#调用flask相关的模块
from flask import Flask, render_template, session, redirect, url_for, flash
from flask.ext.script import Manager
from flask.ext.bootstrap import Bootstrap
from flask.ext.moment import Moment
from flask.ext.wtf import Form
#调用需要用到的表单类型以及属性
from wtforms import TextAreaField,StringField,SubmitField,SelectField,PasswordField
from wtforms.validators import Required,DataRequired
#调用基础模块
import os,commands,subprocess,time,threading
#调用字典文件并加载
from webpath import webpath
from userdata import userdata

app = Flask(__name__)
app.config['SECRET_KEY'] = 'who is your boss'

manager = Manager(app)
bootstrap = Bootstrap(app)
moment = Moment(app)

#函数:获取指定格式的当前时间
def gettime():
ISOTIMEFORMAT='%Y-%m-%d %X' #指定时间格式
ttime = time.strftime( ISOTIMEFORMAT,time.localtime(time.time())) #获取当前时间
return ttime

#函数:将输出转换为列表
def make_list(listin,symbol):
tem = listin.replace(symbol,'') #将指定内容替换为空
tem1 = tem.splitlines() #按照行将输入转换为列表
return tem1

#函数:输出日志
def inputF(con):
f = open('seos.log','a') #以追加的模式打开文件,如果没有,创建
updatetime = gettime()
uptime = str(updatetime) + '\n'
f.write(uptime)
conx = con + '\n'
f.write(conx)
f.close() #关闭文件,释放资源

#函数:获取当前存活的web服务器名称,转换为列表
def getweb():
#执行shell命令,获取saltstack中存活的web服务器
p = subprocess.Popen('salt-run manage.up | grep web',shell=True,stdout=subprocess.PIPE)
tem0 = p.stdout.read() #获取脚本执行结果
tem2 = make_list(tem0,'- ')
return tem2

#函数:删除指定web的相关模块缓存
def rmcache_Newseos(webname):
wbapp = 'Wap Weibo'
tem2 = getweb()
basicpath = webpath.get(webname)
#执行脚本,调用saltstack的客户端服务器上的脚本,实现删除缓存功能
res = subprocess.Popen('salt \'%s\' cmd.run \'sh %scleancache.sh %s\'' % (webname, basicpath, wbapp),shell=True,stdout=subprocess.PIPE)

#函数:删除所有web的相关模块缓存
#这个函数是使用线程之前的函数,作用如上,效率比较低
def rmomscache():
p = subprocess.Popen('salt-run manage.up | grep web',shell=True,stdout=subprocess.PIPE)
path = 'oms/Runtime/*'
tem0 = p.stdout.read()
tem2 = make_list(tem0,'- ')
for webname in tem2:
basicpath = webpath.get(webname)
tpath = '%s%s' % (basicpath, path)
res = subprocess.Popen('salt \'%s\' cmd.run \'rm -rf %s\'' % (webname, tpath),shell=True,stdout=subprocess.PIPE)
res_in = res.stdout.read()
print res_in
print tpath
return 'Delete oms cache!'

#函数:删除指定web的指定模块缓存
def rmomscache_new(webname):
path = 'oms/Runtime/*'
basicpath = webpath.get(webname)
tpath = '%s%s' % (basicpath, path)
res = subprocess.Popen('salt \'%s\' cmd.run \'rm -rf %s\'' % (webname, tpath),shell=True,stdout=subprocess.PIPE)

#函数:创建线程集合
def getthreads(targets):
allweb = getweb()
threads = []
for webname in allweb:
t = threading.Thread(target=targets, args=(webname,))
threads.append(t)
return threads

#函数:升级网站
def update_web(path):
f = open('resault.txt','a')
tem2 = getweb()
for webname in tem2:
basicpath = webpath.get(webname)
tpath = '%s%s' % (basicpath, path)
res = subprocess.Popen('salt \'%s\' cmd.run \'svn update %s\'' % (webname, tpath),shell=True,stdout=subprocess.PIPE)
res_in = res.stdout.read()
f.write(str(res_in))
res_list = make_list(res_in,' ')
f.close()
resault = open('resault.txt').read()
f.close()
os.remove('resault.txt')
return resault

#定义表单
class NameForm(Form):
uppath = SelectField('Path', choices=[('do','do'),('oms','oms')])
username = SelectField('User', choices=[('admin','admin'),('liujian','liujian')])
upkey = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Update')

@app.errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404

@app.errorhandler(500)
def internal_server_error(e):
return render_template('500.html'), 500

#主程序
@app.route('/', methods=['GET', 'POST'])
def index():
name = None
uppath = None
username = None
upkey = None
passwd = None
rmcache = 'Does it need to delete the cache'
form = NameForm()
if form.validate_on_submit():
uppath = form.uppath.data
upkey = form.upkey.data
username = form.username.data
passwd = userdata.get(username)
if upkey is None or upkey != passwd:
flash('Your key is wrong!')
session['name'] = 'Please input right key.'
session['rmcache'] = 'Does it need to delete the cache'
return redirect(url_for('index'))
else:
utime = gettime()
print '%s Start update WEB' % utime
resaul = update_web(uppath)
resault = resaul.replace('\n','<br>')
session['name'] = resault
if uppath.startswith('Newseos'):
Newseostime = gettime()
print '%s Newseos is updated,start remove cache.' % Newseostime
threads = getthreads(rmcache_Newseos)
for t in threads:
t.setDaemon(True)
t.start()
t.join()
endtime = gettime()
print '%s Newseos upgrade over!' % endtime
session['rmcache'] = 'Delete Newseos Cache.'
uplog = 'Operator:' + username + '\n' + 'Update Path:' + uppath + '\n' + resaul
inputF(uplog)
return redirect(url_for('index'))
elif uppath.startswith('oms'):
omstime = gettime()
print '%s oms id updated,start remove cache.' % omstime
threads = getthreads(rmomscache_new)
for t in threads:
t.setDaemon(True)
t.start()
t.join()
endtime = gettime()
print '%s oms upgrade over!' % endtime
session['rmcache'] = 'Delete oms Cache.'
uplog = 'Operator:' + username + '\n' + 'Update Path:' + uppath + '\n' + resaul
inputF(uplog)
return redirect(url_for('index'))
else:
session['rmcache'] = 'No need delete cache.'
uplog = 'Operator:' + username + '\n' + 'Update Path:' + uppath + '\n' + resaul
inputF(uplog)
return redirect(url_for('index'))
return render_template('index.html', form=form, name=session.get('name'), uppath=uppath, upkey=upkey, username = username, rmcache=session.get('rmcache'))

if __name__ == '__main__':
manager.run()

结语:模板相关的代码以及整体程序结构没有展示,感觉必要性也不是很大。下边给出我参考和学习的一些资料和链接吧:

书籍:

《Flask Web开发-基于Python的Web应用开发实战》 ---核心书籍
《Python 核心编程》第二版
链接:
linux部署flask+uwsgi+nginx详解 http://www.tuicool.com/articles/zUvqMr flask学习的博客 http://my.oschina.net/ykbj/blog

页面展示:

页面实现功能:

选择更新路径、更新密码验证、自动删除缓存、更新结果反馈、更新日志记录

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: