複数のリモート サーバーでさまざまなサービスを管理する Python "スクリプト" の例:
以下は、SSH アクセスできるサーバー上のさまざまなサービスを管理するために使用できるハッキングされたスクリプトです。
理想的には、ssh-agent を実行するか、パスフレーズを何度も入力する必要があります。
リモート マシンで昇格された権限を必要とするコマンドの場合、「sudo」が呼び出されていることがわかります。これは、各リモート マシンで sudoers ファイルを変更し、次のようなエントリを追加する必要があることを意味します (ユーザー名 == と仮定しますdeploy)。
Defaults:deploy !requiretty
Defaults:deploy !authenticate
deploy ALL=\
/sbin/service httpd status,\
/sbin/service httpd configtest,\
/sbin/service httpd graceful
最初の 2 行により、deployユーザーsudoは tty を使用したり、パスワードを再入力したりしなくても実行できます。つまり、それ以上入力せずに ssh 経由で直接実行できます。sudoリモートで利用する python コマンドの例を次に示します。
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd graceful'))
とにかく、これはあなたの質問に対する「ストレートな」答えではなく、Python と他のいくつかの手法を使用して、特定のニーズに 100% 合わせたシステム管理ツールを作成する方法がいかに簡単かを示しています。
ところで、次のスクリプトは、いずれかのコマンドが終了ステータス > 0 を返した場合に「明確に伝える」ため、出力を自分で分析できます。
これは、私が取り組んでいたプロジェクトがロード バランサーの使用を開始したときに一緒にハッキングされ、各サーバーですべてのコマンドを実行することが公平ではなくなりました。これを変更または拡張して、rsync と連携してファイルを展開したり、リモート サーバーでホストするスクリプトに更新を展開して「作業を行ったり」することもできます。
#!/usr/bin/python
from optparse import OptionParser
import subprocess
import sys
def die(sMessage):
print
print sMessage
print
sys.exit(2)
###################################################################################################
# Settings
# The user@host: for the SourceURLs (NO TRAILING SLASH)
RemoteUsers = [
"deploy@ac10.example.com",
"deploy@ac11.example.com",
]
###################################################################################################
# Global Variables
# optparse.Parser instance
Parser = None
# optparse.Values instance full of command line options
Opt = None
# List of command line arguments
Arg = None
###################################################################################################
Parser = OptionParser(usage="%prog [options] [Command[, Subcommand]]")
Parser.add_option("--interactive",
dest = "Interactive",
action = "store_true",
default = False,
help = "Ask before doing each operation."
)
# Parse command line
Opt, Arg = Parser.parse_args()
def HelpAndExit():
print "This command is used to run commands on the application servers."
print
print "Usage:"
print " deploy-control [--interactive] Command"
print
print "Options:"
print " --interactive :: will ask before executing each operation"
print
print "Servers:"
for s in RemoteUsers: print " " + s
print
print "Web Server Commands:"
print " deploy-control httpd status"
print " deploy-control httpd configtest"
print " deploy-control httpd graceful"
print " deploy-control loadbalancer in"
print " deploy-control loadbalancer out"
print
print "App Server Commands:"
print " deploy-control 6x6server status"
print " deploy-control 6x6server stop"
print " deploy-control 6x6server start"
print " deploy-control 6x6server status"
print " deploy-control wb4server stop"
print " deploy-control wb4server start"
print " deploy-control wb4server restart"
print " deploy-control wb4server restart"
print
print "System Commands:"
print " deploy-control disk usage"
print " deploy-control uptime"
print
sys.exit(2)
def YesNo(sPrompt):
while True:
s = raw_input(sPrompt)
if s in ('y', 'yes'):
return True
elif s in ('n', 'no'):
return False
else:
print "Invalid input!"
# Implicitly verified below in if/else
Command = tuple(Arg)
if Command in (('help',), ()):
HelpAndExit()
ResultList = []
###################################################################################################
for UH in RemoteUsers:
print "-"*80
print "Running %s command on: %s" % (Command, UH)
if Opt.Interactive and not YesNo("Do you want to run this command? "):
print "Skipping!"
print
continue
#----------------------------------------------------------------------------------------------
if Command == ('httpd', 'configtest'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd configtest'))
#----------------------------------------------------------------------------------------------
elif Command == ('httpd', 'graceful'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd graceful'))
#----------------------------------------------------------------------------------------------
elif Command == ('httpd', 'status'):
CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd status'))
#----------------------------------------------------------------------------------------------
elif Command == ('loadbalancer', 'in'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/loadbalancer-in'))
#----------------------------------------------------------------------------------------------
elif Command == ('loadbalancer', 'out'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/loadbalancer-out'))
#----------------------------------------------------------------------------------------------
elif Command == ('disk', 'usage'):
CommandResult = subprocess.call(('ssh', UH, 'df -h'))
#----------------------------------------------------------------------------------------------
elif Command == ('uptime',):
CommandResult = subprocess.call(('ssh', UH, 'uptime'))
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'status'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-status'))
if CommandResult > 0:
print "Servers not running!!!"
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'stop'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-stop'))
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'start'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-start'))
#----------------------------------------------------------------------------------------------
elif Command == ('6x6server', 'restart'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/6x6server-restart'))
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'status'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-status'))
if CommandResult > 0:
print "Servers not running!!!"
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'stop'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-stop'))
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'start'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-start'))
#----------------------------------------------------------------------------------------------
elif Command == ('wb4server', 'restart'):
CommandResult = subprocess.call(('ssh', UH, 'bin-slave/wb4server-restart'))
#----------------------------------------------------------------------------------------------
else:
print
print "#"*80
print
print "Error: invalid command"
print
HelpAndExit()
#----------------------------------------------------------------------------------------------
ResultList.append(CommandResult)
print
###################################################################################################
if any(ResultList):
print "#"*80
print "#"*80
print "#"*80
print
print "ERRORS FOUND. SEE ABOVE"
print
sys.exit(0)
else:
print "-"*80
print
print "Looks OK!"
print
sys.exit(1)