自动化运维管理fabric

网友投稿 631 2023-02-12

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

自动化运维管理fabric

fabric 常用接口

fabric是对ssh的一个集成工具,对我们而言只需要使用相应的接口,来高效的完成工作,我们常用到的功能基本是 : 本地或者远端执行命令, 分发文件,收集文件,还有一些权限相关的操作。 这些fabric都给我们提供了对应的接口。如下所示:

1
2
3
4
5
6
7
run(fabric.operations.run)
sudo(fabric.operations.sudo)
local(fabric.operations.local)
get(fabric.operations.get)
put(fabric.operations.put)
prompt(fabric.operations.prompt)
reboot(fabric.operations.reboot)

fabric 还提供了上下文管理器

接口部分提供了命令运行的方式,不过都无法保持上下文关系,为了解决这个问题,fabric的context manager 就派上了用场:

1
2
3
4
5
cd(fabric.context_managers.cd)
lcd(fabric.context_managers.lcd)
path(fabric.context_managers.path)
settings(fabric.context_managers.settings)
prefix(fabric.context_managers.prefix)

fabric 安装

1
easy_install fabric

fabric 编程模型介绍

1
2
3
4
5
from fabric.api import *
def helloworld(who='world'):
print"Hello {0}!".format(who)
def helloworld1(you='world',me='ruiaylin'):
print"Hello {0}! i am {1} ! ".format(you,me)

执行命令(其中参数的传递直接跟在任务后跟变量名和参数):

1
2
3
4
5
6
fabric  fab-fhelloword.py  helloworld
Hello world!
Done.
fabric  fab-fhelloword.py  helloworld1:you='ruichao',me='ruiaylin'
Hello ruichao!iam ruiaylin!
Done.

fabric主要接口方法

我们已经看了一个简单例子下面我们来看一下fabric的主要接口。

run (fabric.operations.run)

Fabric 中使用最多的就是 run 方法了。run是用来在一台或者多台远程主机上面执行shell 命令。

方法的返回值是可以通过变量来进行捕获可以通过变量的.failed 和 .succeeded 来检查命令是否执行成功还有一个很赞的就是 run 方法中执行命令的时候,可以支持awk 很给力

使用方法:

sudo (fabric.operations.sudo)

使用 sudo 命令执行对顶的命令。使用方法与run 类似。

local (fabric.operations.local)

local 命令是执行本机的命令或者脚本.使用方法和run 还有sudo类似,但是有一个区别就是: 捕获结果的时候,是通过指定 capture=False 或者capture=True来确定。来看实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# example like this :
def helloworld(who='world'):
print"Hello {0}!".format(who)
yy=local(" pwd ",capture=False)
print'start :  yy = ',yy,' : ::  ',yy.succeeded
zz=local(" pwd ",capture=True)
print'start :  zz = ',zz,' : ::  ',zz.succeeded
#result :
fabric  fab-fhelloword.py  helloworld-H10.211.55.3-uroot
[10.211.55.3]Executing task'helloworld'
Hello world!
[localhost]local:pwd
/Users/ruiaylin/Documents/workpython/fabric
start:yy=:::True
[localhost]local:pwd
start:zz=/Users/ruiaylin/Documents/workpython/fabric:::True

get (fabric.operations.get)

get 方法是从远程主机 copy file 到本地,功能跟scp一样。可以从远程主机下载备份,或者日志文件等等。

通过参数 remote_path 指定远程文件的路径通过参数 local_path 指定远程文件的路径

使用方法如下:

1
2
3
4
# Download some logs
get(remote_path="/tmp/xxx.log",local_path="/tmp/xxx.log")
# Download a database back-up
get("/backup/db.gz","./db.gz")

put (fabric.operations.put)

某些需要上传和分发文件的时候,put命令就派上了用场,使用方式类似 get。也同样可以通过.failed .succeeded进行命令是否执行成功的判断。

local_path - 本地路径remote_path - 远程路径mode - 文件属性

如下例子:

1
upload=put("requirements.txt","requirements.txt",mode=0664)

并行执行

目前官方来看 1.X 版本的fabric 并行执行的时候不是thread safe的。如果需要并行执行task。需要在方法上面使用注解 @parallel 为了防止管控机器上面过多的并发任务可以通过 @parallel(pool_size=5)来设置. 并行的执行输出都会输出到一个终端上面,比较混乱。最好是写到日志,以task为维度。跟下面的代码类似。

MySQL 安装实例

安装步骤如下

基本脚本如下:

script 1 sub task :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
fromfabric.api import*
fromfabric.colors importgreen,red,blue,cyan,yellow
importos,sys
importsocket
importdatetime
importlogging
importlogging.handlers
#get logger for logging
definitLoggerWithRotate():
logname=''.join(env.host_string.split('.'))+'.log'
logFileName="logs/%s"%logname
logger=logging.getLogger("fabric")
formater=logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s","%Y-%m-%d %H:%M:%S")
file_handler=logging.handlers.RotatingFileHandler(logFileName,maxBytes=104857600,backupCount=5)
file_handler.setFormatter(formater)
stream_handler=logging.StreamHandler(sys.stderr)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
logger.setLevel(logging.INFO)
returnlogger
#mkdir
defrunmkdir(dir):
run(''' mkdir -p %s '''%dir)
#stp 1 check host
defcheckhost(logger):
host=env.host_string
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
flag_c=0
try:
s.connect((host,22))
flag_c=1
logger.info(green(' --> host %s can be reachable '%host))
exceptsocket.error ase:
logger.warning(yellow(' --> Error on connect %s'%e))
s.close()
returnflag_c
#stp 2 check alive instance on target host
defcheckmysqlinstance(logger):
try:
wc=run(''' ps -ef |grep mysqld|grep  -v safe | grep -v grep | wc -l  ''')
ifint(wc)>0:
logger.warning(yellow(' --> %sinstance exist on the target host  '%wc))
portraw=run('''  ps -ef |grep mysqld|grep -v safe |grep -v grep  |awk ' {for(i=1;i<=NF;i++){if($i ~/--port/ ){print $i}}}' |awk -F '=' '{print $2}'
            ''')
ports=[x.strip()forxinportraw.split()]
logger.warning(yellow(' --> existing instance port : [ %s ] '%(','.join(ports))))
ifport inports:
logger.error(red(' --> Install port %s exist , install failed '%port))
logger.error(red(' <<<exit>>>>>  task on host %s stop & exit() '%thost))
sys.exit()
exceptException,e:
logger.warning(yellow(' --> checkmysqlinstance() exception : %s '%e))
raisee
#stp 3 initdir for installation
defcreateUser(logger,user='mysql',group='dba'):
try:
ifint(run('grep "^mysql" /etc/passwd|wc -l'))==0:
run('groupadd dba ')
run('useradd -c "mysql software owner" -g dba -G dba mysql')
run('mkdir -p /home/mysql ; chown -R mysql.dba /home/mysql ')
logger.info(cyan(' --> create user [ mysql ] in group [ dba ]  success '))
else:
logger.info(yellow(' --> user [ mysql ] in group [ dba ] exist & skip  '))
exceptException,e:
logger.warning(yellow(' --> createUser() exception : %s '%e))
raisee
#stp 4 initail directory for mysql        
definitdir(logger,port=3306):
try:
logger.info(green(' --> begin to create dirs for installation '))
datadir='/data/'
logdir='/log/'
mandir='mysql%s'%port
subddir='/data/mysql%s/{data,log,run,tmp}'%(port)
subldir='/log/mysql%s/{binlog,iblog}'%(port)
#data
ck1=run(' df -vh  | grep  /data | wc -l ')
ifck1==0:
logger.error(green(' --> no /data/ partition exist'))
#sys.exit()
ifint(run(' ls /  | grep  /data | wc -l '))==0orint(run(' ls /data/ | grep -w %s | wc -l '%mandir))==0:
runmkdir(subddir)
logger.info(green(' --> /data/*** create Ok '))
else:
logger.info(green(' --> /data/mysql%s exsit '%port))
logger.info(green(' --> pls,handle it and restart this task '))
sys.exit()
#log
ck2=run(' df -vh | grep /log/  | wc -l  ')
ifint(run(' df -vh | grep /log/  | wc -l  '))==0andint(run(' ls / | grep -w log  | wc -l  '))==0:
logger.warning(yellow(' --> no /log/ partition exist'))
logger.warning(yellow(' --> create link for /log/ --> /data/log/'))
runmkdir('/data/log')
run('ln -s /data/log  /log ')
runmkdir(subldir)
logger.info(green(' --> /log/*** create Ok '))
else:
ifint(run(' ls /log/ | grep -w %s | wc -l '%mandir))==0:
runmkdir(subldir)
logger.info(green(' --> /log/*** create Ok '))
else:
logger.info(yellow(' --> /log/mysql%s exsit '%port))
logger.error(red(' --> pls,handle it and restart this task '))
sys.exit()
#change
runmkdir('/data/tmp')
logger.info(green(' --> change dirs owner&privs start'))
run('chown -R mysql:dba /data/*')
run('chown -R mysql:dba /log')
logger.info(green(' --> change dirs owner&privs done'))
exceptException,e:
logger.warning(yellow(' --> initdir() exception : %s '%e))
raisee
#stp 5 put mysql install package
defcopymysql(logger,version='5.7'):
try:
dits={
'ubuntu':'mysql-server_5.6.21-1ubuntu12.04_amd64.deb-bundle.tar',
'centos':'mysql-server.tar.gz'
}
issue=run('cat /etc/issue')
ss=issue.lower()
logger.info(green(' %s '%ss))
ifint(run(' ls /usr/local/ | grep mysql | wc -l '))>0:
logger.info(yellow(' --> mysql software installed , skip   '))
return
plats=dits.keys()
forxinplats:
ifss.find(x)!=-1:
logger.info(green(' --> the target host platform is %s'%x))
put(local_path="configs/%s"%dits[x],remote_path="/tmp/%s"%dits[x])
logger.info(green(' --> tar the ball to prop dir '))
run('tar zxvf /tmp/%s -C /usr/local/ '%dits[x])
run('ln -s /usr/local/%s  /usr/local/mysql  '%dits[x][:-7])
break
exceptException,e:
logger.warning(yellow(' --> copymysql() exception : %s '%e))
raisee
#gen my.cnf file
defgetnewServerId(logger,port):
host=env.host_string
print'getnewServerId : ',host
pics=host.split('.')
a=int(pics[0])
b=int(pics[1])
c=int(pics[2])
d=int(pics[3])
suf=int(port)%256
server_id=b*256*256*256+c*256*256+d*256+suf
logger.info(cyan(' --> gen server_id done , %s %s is %s '%(host,port,server_id)))
returnserver_id
defgenmycnf(logger,port=3306,itype='h'):
host=env.host_string
bps={
"a":"48|32|3100|3000",
"b":"62|40|4600|4500",
'c':'94|64|7600|7500',
'd':'94|32|3100|3000',
'e':'125|75|10100|10000',
'f':'188|120|15100|15000',
'g':'188|60|7600|7500',
'h':'1|256M|800|750'
}
try:
myfile=''.join(host.split('.'))+'.cnf'
cpmycnf="""cp configs/my.cnf  tmp/%s """%myfile
local('rm -f  tmp/%s'%myfile)
local("cp configs/my.cnf tmp/%s "%myfile)
sid=getnewServerId(logger,port)
keys=bps.keys()
bpxs=bps[itype]
mem,bpsize,maxc,maxuc=bpxs.split('|')
ifbpsize[-1]!="M":
bpsize=bpsize+'g'
chrgcmd="""  sed -i -e "s/3306/%s/g" -e "s/server_id=10000/server_id=%s/g" -e "s/=32g/=%s/g" -e "s/max_connections=3100/max_connections=%s/g" -e "s/max_user_connections=3000/max_user_connections=%s/g" tmp/%s """
local(chrgcmd%(port,sid,bpsize,maxc,maxuc,myfile))
logger.info(green(' --> gen my.cnf success  '))
logger.info(green(' --> copy my.cnf to dist host '))
put(local_path="tmp/%s"%myfile,remote_path="/data/mysql%s/my.cnf"%(port))
exceptException,e:
logger.warning(yellow(' --> genmycnf() exception : %s '%traceback.format_exc()))
raisee

script 2 whole task :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
importinst_utils
frominst_utils import*
definstall_mysql(port):
logger=initLoggerWithRotate()
thost=env.host_string
try:
logger.info(green('stp 1 get the host %s '%thost))
#check host reachable  
rs1=checkhost(logger)
ifint(rs1)==0:
logger.info(red('stp 2 check the host is reachable failed '))
logger.info(green('stp 2 check the host is reachable OK '))
plat_type=run(''' uname -o ''')
ifplat_type!='GNU/Linux':
logger.warning(yellow('stp 3 target platform is not GNU/Linux & exit() '))
sys.exit()
logger.info(green('stp 3 target platform is GNU/Linux'))
#check target host exsist mysql instance
logger.info(green('stp 4 checkmysqlinstance  '))
checkmysqlinstance(logger)
#create MySQL user
logger.info(green('stp 5 createUser '))
createUser(logger)
put(local_path="configs/bash_profile",remote_path="/home/mysql/.bash_profile")
#checking dir
logger.info(green('stp 6 initdir '))
initdir(logger,port)
#copy file
logger.info(green('stp 7 copymysql '))
copymysql(logger)
logger.info(green('stp 8  genmycnf  '))
genmycnf(logger,port,'h')
exceptException,e:
print'main : exception : ',e
上一篇:包含系统性能测试数据分析报告的词条
下一篇:硬盘告警怎么处理(硬盘告警怎么处理好)
相关文章

 发表评论

评论列表