±à¼ÍƼö: |
À´Ô´ÓÚcnblogs£¬FabricÊÇ»ùÓÚPythonʵÏÖµÄSSHÃüÁîÐй¤¾ß£¬¼ò»¯ÁËSSHµÄÓ¦ÓóÌÐò²¿Êð¼°ÏµÍ³¹ÜÀíÈÎÎñ. |
|
¼ò½é:FabricÌṩÁËϵͳ»ù´¡µÄ²Ù×÷×é¼þ£¬¿ÉÒÔʵÏÖ±¾µØ»òÔ¶³ÌshellÃüÁ°üÀ¨£ºÃüÁîÖ´ÐС¢ÎļþÉÏ´«¡¢ÏÂÔØ¼°ÍêÕûÖ´ÐÐÈÕÖ¾Êä³öµÈ¹¦ÄÜ¡£FabricÔÚParamikoµÄ»ù´¡ÉÏ×öÁ˸ü¸ßÒ»²ãµÄ·â×°£¬²Ù×÷ÆðÀ´»á¸ü¼Ó¼òµ¥¡£
°²×°Fabric
ʹÓÃpip install FabricÀ´°²×°,°²×°ÐèÒªparamiko°üºÍCrypto°ü ÑéÖ¤ÊÇ·ñ°²×°³É¹¦£¬³öÏÖÈçÏÂͼËùʾ£¬ËµÃ÷fabricÄ£¿é°²×°³É¹¦
ÃüÁî˵Ã÷
1.¸ñʽ
fab [options]
<command> [:arg1,arg2=val2, host=foo, hosts='h1;h2',...]
... |
2. ³£ÓòÎÊý
-l #ÏÔʾ¶¨ÒåºÃµÄÈÎÎñº¯ÊýÃû
-f #Ö¸¶¨fabÈë¿ÚÎļþ£¬Ä¬ÈÏÈë¿ÚÎļþÃûΪfabfile.py
-f #Ö¸¶¨Íø¹Ø£¨ÖÐת£©É豸£¬±ÈÈ籤ÀÝ»ú»·¾³£¬Ìî䱤ÀÝ»úIP¼´¿É
-H #Ö¸¶¨Ä¿±êÖ÷»ú£¬¶ą̀Ö÷»úÓá®,¡¯ºÅ·Ö¸ô
-p #Ô¶³ÌÕ˺ŵÄÃÜÂ룬fabÖ´ÐÐʱĬÈÏʹÓÃrootÕË»§
-P #ÒÔÒì²½²¢Ðз½Ê½ÔËÐжàÖ÷»úÈÎÎñ£¬Ä¬ÈÏΪ´®ÐÐÔËÐÐ
-R #Ö¸¶¨role£¨½ÇÉ«£©£¬ÒÔ½ÇÉ«ÃûÇø·Ö²»Í¬ÒµÎñ×éÉ豸
-t #ÉèÖÃÉ豸Á¬½Ó³¬Ê±Ê±¼ä£¨Ã룩
-T #ÉèÖÃÔ¶³ÌÖ÷»úÃüÁîÖ´Ðг¬Ê±Ê±¼ä£¨Ã룩
-w #µ±ÃüÁîÖ´ÐÐʧ°Ü£¬·¢³ö¾¯¸æ£¬¶ø·ÇĬÈÏÖÐÖ¹ÈÎÎñ¡£ |
ʾÀý
±àдһ¸öfabfile.pyÎļþ
vim fabfile.py
#!/usr/bin/env
python
# -*- coding:utf-8 -*-
from fabric.api import run
#¶¨ÒåÒ»¸öÈÎÎñº¯Êý£¬Í¨¹ýrun·½·¨ÊµÏÖÔ¶³ÌÖ´ÐС®uname -s¡¯ÃüÁî
def host_type():
run('uname -s') |
fabÃüÁî²Ù×÷£º
fab -H localhost
host_type
#½á¹û£º
[localhost] Executing task 'host_type'
[localhost] run: uname -s
[localhost] Login password for 'root':
[localhost] out: Linux
[localhost] out:
Done.
Disconnecting from localhost... done. |
ÉÏÃæÊµÀýÒ²¿ÉÒÔд³ÉÒ»ÐдúÂ룺
fab -p 123456
-H localhost -- 'uname -s' #--ºóÃæÒª¼Ó¿Õ¸ñ |
fabfileÎļþµÄ±àд
fabÃüÁîÊǽáºÏfabfile.pyÎļþ£¨ÆäËûÎļþͨ¹ý-f filename ²ÎÊýÀ´ÒýÓã©À´´îÅäʹÓõġ£fabµÄ²¿·ÖÃüÁîÐвÎÊý»¹ÄÜͨ¹ýÏàÓ¦µÄ·½·¨À´´úÌæ¡£
È磺
fab -H 192.168.1.21,192.168.1.22
... ...
#¿ÉÒÔÔÚfabfile.pyÎļþÖÐÓÃenv.hostsÀ´ÊµÏÖ£¬ÃüÁîÐÐÖоͿÉÒÔ²»ÓÃдÁË
#¿ÉÒÔÔÚfabfileÖÐÕâôд£º
env.hosts = ['192.168.1.21','192.168.1.22'] |
fabfileÖ®env¶ÔÏó
env¶ÔÏóµÄ×÷ÓÃÊǶ¨ÒåfabfileµÄÈ«¾ÖÉ趨£¬¾ÍÏñÉÏÃæµÄ¾ÙÀý¡£ÏÂÃæ¶Ô¸÷ÊôÐÔ½øÐÐ˵Ã÷£º
env.hosts #¶¨ÒåÄ¿±êÖ÷»ú£¬¿ÉÒÔÓÃIP»òÖ÷»úÃû±íʾ£¬ÒÔpythonµÄÁбíÐÎʽ¶¨Òå¡£Èçenv.hosts=['192.168.1.21','192.168.1.22']
env.exclude_hosts #ÅųýÖ¸¶¨Ö÷»ú£¬Èçenv.exclude_hosts=['192.168.1.21']
env.user #¶¨ÒåÓû§Ãû£¬Èçenv.user='root'
env.port #¶¨Òå¶Ë¿Ú£¬Ä¬ÈÏΪ22£¬Èçenv.port='22'
env.password #¶¨ÒåÃÜÂ룬Èçenv.password='123456'
env.passwords #¶¨Òå¶à¸öÃÜÂ룬²»Í¬Ö÷»ú¶ÔÓ¦²»Í¬ÃÜÂ룬È磺env.passwords
= {'root@192.168.1.21:22':'123456', 'root@192.168.1.22:22':'654321'}
env.gateway #¶¨ÒåÍø¹Ø£¨ÖÐת¡¢±¤ÀÝ»ú£©IP£¬Èçenv.gateway='192.168.1.23
env.roledefs #¶¨Òå½ÇÉ«·Ö×飬±ÈÈçweb×éºÏdb×éÖ÷»úÇø·Ö¿ªÀ´£ºenv.roledefs
= {'webserver':['192.168.1.21', '192.168.1.22'],
'dbserver':['192.168.1.25','192.168.1.26']}
env.deploy_release_dir #×Ô¶¨ÒåÈ«¾Ö±äÁ¿£¬¸ñʽ£ºenv. + '±äÁ¿Ãû³Æ'£¬Èçenv.age,env.sexµÈ |
env.roledefsµÄʹÓ÷½·¨ÊµÀý£º
env.roledefs =
{'webserver':['192.168.1.21','192.168.1.22'],'dbserver':['192.168.1.25','192.168.1.26']}
#ÒýÓ÷Ö×éʱʹÓÃpython×°ÊÎÆ÷·½Ê½À´½øÐÐ,È磺
@roles('webserver')
def webtask():
run('/usr/local/nginx/sbin/nginx')
@roles('webserver','dbserver')
def publictask():
run('uptime') |
Fabric³£ÓÃAPI
×îÉÏÃæµÄ¼òµ¥ÊµÀýÖÐʹÓÃÁËapiº¯Êýrun,ÏÂÃæÔÙÁоټ¸¸ö³£ÓõÄapi¡£
local #Ö´Ðб¾µØÃüÁÈçlocal('uname
-s')
lcd #Çл»±¾µØÄ¿Â¼£¬Èçlcd('/home')
cd #Çл»Ô¶³ÌĿ¼
run #Ö´ÐÐÔ¶³ÌÃüÁî
sudo #sudo·½Ê½Ö´ÐÐÔ¶³ÌÃüÁÈçsudo('/etc/init.d/httpd start')
put #Éϴα¾µØÎļþµ¼Ô¶³ÌÖ÷»ú£¬Èçput('/home/user.info','/data/user.info')
get #´ÓÔ¶³ÌÖ÷»úÏÂÔØÎļþµ½±¾µØ£¬È磺get('/data/user.info','/home/user.info')
prompt #»ñµÃÓû§ÊäÈëÐÅÏ¢£¬È磺prompt('please input user password:')
confirm #»ñµÃÌáʾÐÅϢȷÈÏ£¬È磺confirm('Test failed,Continue[Y/N]?')
reboot #ÖØÆôÔ¶³ÌÖ÷»ú£¬È磺reboot()
@task #º¯ÊýÐÞÊηû£¬±êʶµÄº¯ÊýΪfab¿Éµ÷Óõģ¬·Ç±ê¼Ç¶Ôfab²»¿É¼û£¬´¿ÒµÎñÂß¼
@runs_once #º¯ÊýÐÞÊηû£¬±êʶµÄº¯ÊýÖ»»áÖ´ÐÐÒ»´Î£¬²»Êܶą̀Ö÷»úÓ°Ïì
|
FabricÓ¦ÓÃʾÀý˵Ã÷
1¡¢²é¿´±¾µØÓëÔ¶³ÌÖ÷»úÐÅÏ¢
±¾Ê¾Àýµ÷ÓÃlocal·½·¨Ö´Ðб¾µØÃüÁÌí¼Ó@runs_onceÐÞÊηû±£Ö¤ÈÎÎñº¯ÊýÖ»Ö´ÐÐÒ»´Î£¬µ÷ÓÃrun·½·¨Ö´ÐÐÔ¶³ÌÃüÁî¡£
#!/usr/bin/env
python
# -*- encoding: utf-8 -*-
from fabric.api import *
env.user = 'root'
env.hosts = ['192.168.1.22']
env.password = '123456'
@runs_once #²é¿´±¾µØÏµÍ³ÐÅÏ¢£¬µ±Óжą̀Ö÷»úʱֻÔËÐÐÒ»´Î
def local_task(): #±¾µØÈÎÎñº¯Êý
local('uname -a')
def remote_task():
with cd('/var/logs'): #withµÄ×÷ÓÃÊÇÈúóÃæµÄ±í´ïʽÓï¾ä¼Ì³Ðµ±Ç°×´Ì¬£¬ÊµÏÖ£ºcd
/var/logs && ls -lµÄЧ¹û
run('ls -l') |
Ö´ÐУº
fab -f simple1.py
local_task
fab -f simple1.py remote_task |
2¡¢¶¯Ì¬»ñȡԶ³ÌĿ¼Áбí
±¾Àýµ÷ÓÃ@taskÐÞÊηû±êÖ¾Èë¿Úº¯Êýgo()¶ÔÍⲿ¿É¼û£¬ÅäºÏ@runs_onceÐÞÊηû½ÓÊÕÓû§ÊäÈ룬×îºóµ÷ÓÃworktask()º¯ÊýʵÏÖÔ¶³ÌÃüÁîÖ´ÐС£
#!/usr/bin/env
python
# -*- encoding: utf-8 -*-
from fabric.api import *
env.user = 'root'
env.hosts = ['192.168.1.22']
env.password = '123456'
@runs_once #Ö÷»ú±éÀú¹ý³ÌÖУ¬Ö»ÓеÚһ̨´¥·¢´Ëº¯Êý
def input_raw():
return prompt('please input directoryname:',default='/root')
def worktask(dirname):
run('ls -l'+dirname)
@task #ÏÞ¶¨Ö»ÓÐgoº¯Êý¶ÔfabÃüÁî¿É¼û,ÆäËûûÓÐʹÓÃ@task±ê¼ÇµÄº¯ÊýfabÃüÁî²»¿ÉÓÃ
def go():
getdirname = input_raw()
worktask(getdirname) |
Ö´ÐÐ:
¶ÔÓÚÉÏÃæµÄ½á¹û×öÁËһЩ²âÊÔ·¢ÏÖ:
1.ÉèÖÃÁËĬÈÏÖµ,²»ÊäÈë¾ÍÊÇÒÔĬÈÏֵΪ׼,Èç¹û²»ÉèÖÃĬÈÏÖµ,ÄÇôdirname¾ÍÊǿյÄ,ls -lµÄ¾ÍÊÇÄãµÇ¼Óû§µÄ¼ÒĿ¼,ÀýÈçÊÇroot¾ÍÊÇ/root
2.¶ÔÓÚдÔÚgoº¯ÊýϵÄÄÚÈÝ,ÓжàÉÙÖ÷»ú¾Í»áÑ»·¶àÉÙ´Î,ËûÊÇÒÔÖ÷»úΪѻ·µÄ.
3.Õâ¸ö½Å±¾ÊǶÔÓÚËùÓеÄÖ÷»úÁгöͬһ¸öĿ¼,¶ÔÓÚ²»Í¬µÄÖ÷»úÈÃÑ¡Ôñ²»Í¬µÄĿ¼,¿ÉÒÔ¼òµ¥µÄÐÞ¸ÄΪ:
def worktask(dirname):
run('ls -l '+dirname)
@task
def go():
getdirname=raw_input("please input directory:")
worktask(getdirname) |
3.Îļþ´ò°üÉÏ´«Ð£Ñé
#!/usr/bin/env
python
from fabric.api import *
from fabric.colors import *
env.hosts=['192.168.56.30']
env.user='root'
env.passwords={'root@192.168.56.30:22':'rooter'}
@runs_once
@task
def tarfile():
print yellow('tar file ...')
#ʹÓÃwith lcdÃüÁî,·ñÔòÐèҪдȫ·¾¶,Ö±½ÓlcdûÓÃ
with lcd('/var/log'):
local('tar czf messages.tar.gz messages')
@task
def putfile():
print blue('put file ...')
run('mkdir -p /tmp/log')
with cd('/tmp/log'):
#warn_onlyµ±³öÏÖÒì³£µÄʱºò¼ÌÐøÖ´ÐÐ
with settings(warn_only=True):
result=put('/var/log/messages.tar.gz','/tmp/log')
if result.failed and not confirm('put file filed,Continue[Y/N]?'):
abort('Aborting file put task!')
@task
def checkfile():
print red('check file ...')
with settings(warn_only=True):
#±¾µØlocalÃüÁîÐèÒªÅäÖÃcapture=True²ÅÄÜ»ñÈ¡·µ»ØÖµ
lmd5=local('md5sum /var/log/messages.tar.gz',capture=True).split('
')[0]
rmd5=run('md5sum /tmp/log/messages.tar.gz').split('
')[0]
if lmd5==rmd5:
print 'ok'
else:
print 'error'
@task
def go():
tarfile()
putfile()
checkfile() |
ÏÂÃæÊÇÔËÐнá¹û£¬ÓÐÑÕÉ«µÄÇø±ð:
[192.168.56.30]
Executing task 'go'
tar file ...
[localhost] local: tar czf messages.tar.gz messages
put file ...
[192.168.56.30] run: mkdir -p /tmp/log
[192.168.56.30] put: /var/log/messages.tar.gz
-> /tmp/log/messages.tar.gz
check file ...
[localhost] local: md5sum /var/log/messages.tar.gz
[192.168.56.30] run: md5sum /tmp/log/messages.tar.gz
[192.168.56.30] out: 958b813fd7bdaa61cc206aa1012d8129
/tmp/log/messages.tar.gz
[192.168.56.30] out:
ok
Done.
Disconnecting from 192.168.56.30... done |
4¡¢Íø¹ØÄ£Ê½ÎļþÉÏ´«ÓëÖ´ÐÐ
±¾Àýͨ¹ý¶¨Òåenv.gatewayÍø¹ØÄ£Ê½£¬¼´Ë׳ƵÄÖÐת¡¢±¤ÀÝ»ú»·¾³¡£Í¨¹ýÍø¹Ø¶ÔÆäËûÖ÷»ú½øÐÐÎļþÉÏ´«ºÍÖ´ÐС£
#!/usr/bin/env
python
# -*- encoding: utf-8 -*-
from fabric.api import *
from fabric.context_managers import *
from fabric.contrib.console import confirm
env.user = 'root'
env.gateway = '192.168.1.23' #¶¨Ò層ÀÝ»úIP£¬×÷ΪÎļþÉÏ´«¡¢Ö´ÐеÄÖÐתÉèÖÃ
env.hosts = ['192.168.1.21','192.168.1.22']
env.passwords = {
'root@192.168.1.21:22':'123456',
'root@192.168.1.22:22':'abcdef',
'root@192.168.1.23:22':'123abc', #±¤ÀÝ»úÕ˺ÅÐÅÏ¢
}
lpackpath = '/home/install/lnmp.tar.gz' #±¾µØ°²×°°ü·¾¶
rpackpath = '/tmp/install' #Ô¶³Ì°²×°°ü·¾¶
@task
def put_task(): #ÉÏ´«Îļþ
run('mkdir -p /tmp/install')
#ĬÈÏÇé¿öÏ£¬µ±ÃüÁîÖ´ÐÐʧ°Üʱ£¬Fabric»áÍ£Ö¹Ö´ÐкóÐøÃüÁî¡£ÓÐʱ£¬ÎÒÃÇÔÊÐíºöÂÔʧ°ÜµÄÃüÁî¼ÌÐøÖ´ÐУ¬±ÈÈçrun(¡®rm
/tmp/abc')ÔÚÎļþ²»´æÔÚµÄʱºòÓпÉÄÜʧ°Ü£¬Õâʱ¿ÉÒÔÓÃwith settings(warn_only=True):Ö´ÐÐÃüÁÕâÑùFabricÖ»»á´ò³ö¾¯¸æÐÅÏ¢¶ø²»»áÖжÏÖ´ÐС£
with settings(warn_only=True):
result = put(lpackpath,rpackpath) #ÉÏ´«
if result.failed and not confirm('put file failed,Continue[Y/N]?'):
abort('Aborting file put task!')
@task
def run_task(): #°²×°
with cd('/tmp/install'):
run('tar -zxvf lnmp.tar.gz')
with cd('lnmp/'): #ʹÓÃwith¼Ì³Ð/tmp/installĿ¼λÖÃ״̬
run('./centos.sh')
@task
def go(): #ÉÏ´«¡¢°²×°×éºÏÃüÁî
put_task()
run_task()
simple3.py
simple3.py |
Ö´ÐÐ:
#ÉÏ´«Îļþ
fab simple3.py put_task
#Ö´ÐÐÎļþ
fab simple3.py run_task
#ÉÏ´«²¢Ö´ÐÐ
fab simple3.py go |
|