どのようにfabric自動化日常管理任務と配置を使うか?
16094 ワード
ソース:http://ruiaylin.github.io/2014/11/24/fabric/
fabricの公式紹介:
公式の紹介を見て、はっきりした認識をしてください。
fabricはsshに対する集積ツールであり、私たちにとっては相応のインターフェースを使って効率的に仕事を完成するだけでなく、私たちがよく使う機能は基本的には、ローカルまたはリモートでコマンドを実行し、ファイルを配布し、ファイルを収集し、またいくつかの権限に関する操作があります。これらのfabricは対応するインターフェースを提供してくれます。以下の通りです
インターフェース部分は命令運行の方式を提供していますが、文脈関係を保つことができません。この問題を解決するために、fabricのcontext managerが役に立ちました。
fabricはpythonに基づいていますので、fabricシナリオを書くとpythonスクリプトです。pythonスクリプトを書くように、他のモジュールや他のツールに頼って作業ができます。Fabricスクリプトは、fabツールを介してfabric pythonスクリプトを実行します。fabツールはデフォルトでfabfile.pyを実行します。スクリプトファイル名を-fパラメータで指定することもできます。fabric優勢は多くて、簡単で、便利で、ログ出力がはっきりしています。命令の中でAWK命令を使って、私達はハローワールドのプログラムを見ます。
簡単な例を見ました。次にfabricの主要なインターフェースを見てみます。
run(fabric.operations.run)
ファブリックで一番多く使われているのがrun法です。runは、1台以上のリモートホスト上でshellコマンドを実行するために使用されます。方法の戻り値は、変数によって捕獲可能な である。は、コマンドが実行されたかどうかを変数のfailedおよび.succededによって確認することができます。 もう一つの素晴らしいのは、runメソッドで命令を実行するとき、awkをサポートすることができます。
使用方法:
sudoコマンドを使用してトップに対するコマンドを実行します。使用法はrunに類似している。
local(fabric.operations.local)
localコマンドは、本機のコマンドやスクリプトを実行します。使い方はrunやsudoと似ていますが、キャプチャ結果を指定する場合、capture=Falseまたはcapture=Trueという違いがあります。実例を見る:
get方法はリモートホストのcopy fileからローカルまでで、機能はscpと同じです。リモートホストからバックアップやログファイルなどをダウンロードできます。 パラメータremote_パス を指定します。パラメータlocal_パス を指定します。
使用方法は以下の通りです。
アップロードや配布が必要な場合は、putコマンドが役に立ちます。使い方はgetに似ています。また.failed.succededによって命令が実行されるかどうかの判断もできます。 local_パス remote_パス mode-ファイル属性 以下の例:
現在の公式は1.Xバージョンのfabricが並行して実行する時thread safeのではありません。並列にtaskを実行する必要がある場合。方法の上に注解@parallelを使用する必要があります。制御マシンの上にあまりにも多くの同時タスクがあるのを防ぐために@parallel(pool_usize=5)で設定できます。並列の実行出力はいずれも一つの端末に出力されます。混乱しています。日記を書いて、taskを次元にしたほうがいいです。下のコードと似ています。
もういくつかのインターフェースがあります。みんなはfabric文書を調べられます。
MySQLインストール例
インストール手順は以下の通りですは、ホストip を取得する。 checkホストアクセス性 、linuxプラットフォームの詳細を確認する 運行のmysql例がありますか? 取得対応ポートがあれば インストールするポートと競合するかどうかを確認する は、mysqlユーザおよびグループ を処理する。インストール関連ディレクトリと権限 を処理する。 copyは、ターゲットマシン にパッケージをインストールします。解凍処理は、主なソフトウェアツールをpathパスにソフトで接続する 。は、対応する標準的なプロファイルを生成し、対象機対応ディレクトリ に配信する。初期化データベース データベースを起動する 基本ステップ をインストールしました。
基本スクリプトは以下の通りです。
script 1 sub task:
転載先:https://blog.51cto.com/5007260/1696741
fabricの公式紹介:
公式の紹介を見て、はっきりした認識をしてください。
Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH
for application deployment or systems administration tasks.
More specifically, Fabric is: A tool that lets you execute arbitrary Python functions via
the command line;A library of subroutines (built on top of a lower-level library) to make executing shell commands over SSH easy and Pythonic. Naturally, most users combine these
two things, using Fabric to write and execute Python functions, or tasks, to automate
interactions with remote servers.
fabricはどんな人にサービスできますか?Python
[ SA , ASA, DBA ...]
fabric常用インターフェースfabricはsshに対する集積ツールであり、私たちにとっては相応のインターフェースを使って効率的に仕事を完成するだけでなく、私たちがよく使う機能は基本的には、ローカルまたはリモートでコマンドを実行し、ファイルを配布し、ファイルを収集し、またいくつかの権限に関する操作があります。これらのfabricは対応するインターフェースを提供してくれます。以下の通りです
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が役に立ちました。
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取り付けeasy_install fabric
fabricプログラミングモデルの紹介fabricはpythonに基づいていますので、fabricシナリオを書くとpythonスクリプトです。pythonスクリプトを書くように、他のモジュールや他のツールに頼って作業ができます。Fabricスクリプトは、fabツールを介してfabric pythonスクリプトを実行します。fabツールはデフォルトでfabfile.pyを実行します。スクリプトファイル名を-fパラメータで指定することもできます。fabric優勢は多くて、簡単で、便利で、ログ出力がはっきりしています。命令の中でAWK命令を使って、私達はハローワールドのプログラムを見ます。
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)
コマンドを実行します。パラメータの転送はタスクの後にある変数名とパラメータに直接付けられます。 fabric fab -f helloword.py helloworldHello world! Done.
fabric fab -f helloword.py helloworld1:you='ruichao',me='ruiaylin'Hello ruichao! i am ruiaylin ! Done.
fabric主要インターフェース方法簡単な例を見ました。次にfabricの主要なインターフェースを見てみます。
run(fabric.operations.run)
ファブリックで一番多く使われているのがrun法です。runは、1台以上のリモートホスト上でshellコマンドを実行するために使用されます。
使用方法:
# creat a directoryrun(" mkdir /tmp/testdir/ -p ")# check proce***esult = run("ps -ef |grep mysqld|grep -v safe |grep -v grep | wc -l "#Check if commandresult.failed
sudo(fabric.operations.sudo)sudoコマンドを使用してトップに対するコマンドを実行します。使用法はrunに類似している。
local(fabric.operations.local)
localコマンドは、本機のコマンドやスクリプトを実行します。使い方はrunやsudoと似ていますが、キャプチャ結果を指定する場合、capture=Falseまたはcapture=Trueという違いがあります。実例を見る:
# 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 -f helloword.py helloworld -H 10.211.55.3 -u root
[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と同じです。リモートホストからバックアップやログファイルなどをダウンロードできます。
使用方法は以下の通りです。
# Download some logsget(remote_path="/tmp/xxx.log", local_path="/tmp/xxx.log")
# Download a database back-upget("/backup/db.gz", "./db.gz")
put(fabric.operations.put)アップロードや配布が必要な場合は、putコマンドが役に立ちます。使い方はgetに似ています。また.failed.succededによって命令が実行されるかどうかの判断もできます。
upload = put("requirements.txt", "requirements.txt", mode=664)
並行して実行する現在の公式は1.Xバージョンのfabricが並行して実行する時thread safeのではありません。並列にtaskを実行する必要がある場合。方法の上に注解@parallelを使用する必要があります。制御マシンの上にあまりにも多くの同時タスクがあるのを防ぐために@parallel(pool_usize=5)で設定できます。並列の実行出力はいずれも一つの端末に出力されます。混乱しています。日記を書いて、taskを次元にしたほうがいいです。下のコードと似ています。
もういくつかのインターフェースがあります。みんなはfabric文書を調べられます。
MySQLインストール例
インストール手順は以下の通りです
基本スクリプトは以下の通りです。
script 1 sub task:
from fabric.api import *from fabric.colors import green,red,blue,cyan,yellowimport os , sysimport socketimport datetimeimport loggingimport logging.handlers#get logger for logging def initLoggerWithRotate():
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) return logger#mkdirdef runmkdir(dir):
run(''' mkdir -p %s '''%dir)#stp 1 check hostdef checkhost(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 ) ) except socket.error as e:
logger.warning( yellow( ' --> Error on connect %s' %e ) )
s.close() return flag_c#stp 2 check alive instance on target host def checkmysqlinstance(logger):
try:
wc = run(''' ps -ef |grep mysqld|grep -v safe | grep -v grep | wc -l ''')
if int(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() for x in portraw.split() ]
logger.warning( yellow( ' --> existing instance port : [ %s ] '%( ','.join( ports )))) if port in ports:
logger.error( red( ' --> Install port %s exist , install failed '%port))
logger.error( red( ' <<>>>> task on host %s stop & exit() '%thost))
sys.exit() except Exception, e:
logger.warning(yellow( ' --> checkmysqlinstance() exception : %s '%e ))
raise e
#stp 3 initdir for installationdef createUser(logger,user='mysql',group='dba'):
try: if int(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 ' ))
except Exception, e:
logger.warning(yellow( ' --> createUser() exception : %s '%e ))
raise e#stp 4 initail directory for mysql def initdir(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 ') if ck1 == 0 :
logger.error(green(' --> no /data/ partition exist' ) ) #sys.exit()
if int( run(' ls / | grep /data | wc -l ')) == 0 or int( 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 ') if int( run(' df -vh | grep /log/ | wc -l ') ) == 0 and int( 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 :
if int(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')) except Exception, e:
logger.warning(yellow( ' --> initdir() exception : %s '%e ))
raise e
#stp 5 put mysql install packagedef copymysql(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)) if int ( run( ' ls /usr/local/ | grep mysql | wc -l ') ) > 0 :
logger.info( yellow( ' --> mysql software installed , skip ' ))
return
plats = dits.keys() for x in plats:
if ss.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
except Exception, e:
logger.warning(yellow( ' --> copymysql() exception : %s '%e ))
raise e
#gen my.cnf file def getnewServerId(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) ) ) return server_iddef genmycnf(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('|') if bpsize[-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) ) except Exception, e:
logger.warning(yellow( ' --> genmycnf() exception : %s '%traceback.format_exc() ) )
raise e
script 2 whole task:import inst_utils
from inst_utils import *
def install_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 )
if int(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 ''')
if plat_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')
except Exception, e:
print 'main : exception : ' , e
以上のように、基本的なインストールは、mysqlのインスタンスを起動していないと、いくつかのdb初期化作業は、興味のある学生は自分で行うことができますが、つまりfabricは、オペレータです。転載先:https://blog.51cto.com/5007260/1696741