阶段性总结:
跌跌撞撞的用了一周左右的时间做完了网站自动升级功能,中间遇到了很多的问题,也学到了很多,在此做一个总结。
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
页面展示:
页面实现功能:
选择更新路径、更新密码验证、自动删除缓存、更新结果反馈、更新日志记录
- 自动化运维工具 SaltStack 搭建
原文地址:https://www.ibm.com/developerworks/cn/opensource/os-devops-saltstack-in-cloud/index.html#N10072 ...
- 自动化运维经验谈,以及为什么Docker是革命性的
互联网+的需要 在信息越来越繁杂的互联网时代,公司所运行的项目越来越多,项目相关服务繁多,服务之间存在复杂的依赖关系,运维与管理任务越来越繁重,手工交付需要花费很多的人力与时间,且安全性和时效性均无法 ...
- 企业级自动化运维工具应用实战-ansible
背景 公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备.公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运 ...
- ansible自动化运维
ansible 系统架构 ansible简介 ansible是新出现的自动化运维工具,ansible是一个配置管理和应用部署工具,基于Python开发,集合了众多运维工具(puppet.cfengin ...
- 使用Ansible实现数据中心自动化运维管理
长久以来,IT 运维在企业内部一直是个耗人耗力的事情.随着虚拟化的大量应用.私有云.容器的不断普及,数据中心内部的压力愈发增加.传统的自动化工具,往往是面向于数据中心特定的一类对象,例如操作系统.虚拟 ...
- puppet自动化运维
Puppet实现自动化运维 一.案例分析 1.案例概述: 随着服务器数量的增多,系统管理员任务量也逐渐增加,这时就需要简洁的.强大的框架来完成系统管理任务为实现这一目的,我们将引入一批工具,这批工具是 ...
- 企业级自动化运维工具应用实战ansible
公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备.公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运维老大 ...
- linux自动化运维工具Ansible saltstack Puppet、Chef、Fabric之间的对比
发现分布式是一个发展的趋势,无论是大型网站的负载均衡架构还是大数据框架部署,以及云存储计算系统搭建都离不开多台服务器的连续部署和环境搭建. 当我们的基础架构是分散式或者基于云的,并且我们经常需要处理在 ...
- CMDB 和自动化运维
目录 传统运维和自动化运维的对比 CMDB CMDB 的几种实现方式 传统运维和自动化运维的对比 1.企业中,项目的发布流程 产品经理调研需求 -->三方开会讨论(开发,产品,运维,测试) -– ...
随机推荐
- ACCESS --第一章
一.ACCESS2007的安装 装完整版的office2007办公软件就集成了相应的ACCESS2007 二.主要组成 ACCESS由表.查询.报表.窗体.页.宏和模块组成 1.表 表是存储数据的对象 ...
- SQLHelper
今天学习了.net后,经过老师的一番讲解,似乎对它越来越渴望了,希望自己在接下来的学习当中,能很好的驾驭.net,加油吧, 下面我分享一个操作SQL数据库的代码大全,谢谢观赏.嘿嘿,还是比较长的哦, ...
- wamp出现You don’t have permission to access/on this server提示的解决方法
本地搭建wamp 输入http://127.0.0.1访问正常,当输入http://localhost/ apache出现You don't have permission to access/on ...
- 在ubuntu14.04 64位虚拟机中安装mysql
因为在win10 系统上手贱的将mysql卸载掉了之后有个插件一直无法正常删除导致只能将mysql装到ubuntu虚拟机上, 宝宝心里都是累啊,所以记录下来自己的安装过程2333 命令行操作: &qu ...
- CSS和CSS选择器
一:CSS CSS有三种书写形式(优先级从高到低) 1)行内样式:(内联样式)直接在标签style属性中书写 2)内页样式:在本网页的style标签中书写 3)外部样式:在单独的CSS文件中书写,然后 ...
- jdk环境配置
设置成用户变量就行,无需设置成系统变量. 1.在新弹出窗口上,点系统变量区域下面的新建按钮,弹出新建窗口,变量名为JAVA_HOME,变量值填JDK安装的最终路径,我这里装的地址是D:\Program ...
- POJ 2653
题目大意:一个小孩不断往地上扔棍子,共n根,求结束后共有多少根不与去他相交. 解法思路:典型的判断线段相交问题,利用快速排斥+双跨立判断相交,最后输出没相交的. (图片来源:http://www.2c ...
- 学习maple
定义函数:$f:=(x,y) \rightarrow x^2+y^2$ 类似mathematica的manipulate功能:plots[animate](plot,[f(x,y),x=0..1],y ...
- day26_网络编程第一天
1.网络通信三要素(掌握) IP 端口号 协议(UPD&TCP) 2.UDP协议与TCP协议各自特点(掌握) UDP 1.不需要建立连接: 2.有数据大小限制,每个 ...
- 使用 RequireJS 优化 Web 应用前端
基于 AMD(Asynchronous Module Definition)的 JavaScript 设计已经在目前较为流行的前端框架中大行其道,jQuery.Dojo.MooTools.EmbedJ ...