0
|
1 #!/usr/bin/env python
|
|
2 # -*- coding: utf-8 -*-
|
|
3
|
|
4 """
|
|
5 run a command on some things
|
|
6 """
|
|
7
|
|
8 # imports
|
|
9 import argparse
|
|
10 import os
|
|
11 import subprocess
|
|
12 import sys
|
|
13 import time
|
|
14
|
|
15 # module globals
|
|
16 __all__ = ['print_command', 'call', 'RunCmdParser']
|
|
17 string = (str, unicode)
|
|
18
|
|
19 def print_command(command, **kwargs):
|
|
20 if not isinstance(command, string):
|
|
21 command = subprocess.list2cmdline(command)
|
|
22 print (command)
|
|
23
|
|
24 def call(command, **kwargs):
|
|
25
|
|
26 process = subprocess.Popen(command, **kwargs)
|
|
27 stdout, stderr = process.communicate()
|
|
28 if process.returncode:
|
|
29 cmdline = subprocess.list2cmdline(command)
|
|
30 print cmdline
|
|
31 raise subprocess.CalledProcessError(process.returncode,
|
|
32 cmdline)
|
|
33
|
|
34 def ssh_call(host, command, ssh='ssh'):
|
|
35 call([ssh, host, command], stderr=subprocess.PIPE)
|
|
36
|
|
37
|
|
38 class RunCmdParser(argparse.ArgumentParser):
|
|
39 """CLI option parser"""
|
|
40
|
|
41 def __init__(self, **kwargs):
|
|
42 kwargs.setdefault('formatter_class', argparse.RawTextHelpFormatter)
|
|
43 kwargs.setdefault('description', __doc__)
|
|
44 argparse.ArgumentParser.__init__(self, **kwargs)
|
|
45 self.add_argument('-H', '--host', dest='hosts', nargs='+',
|
|
46 help="hosts to run on; or read from stdin if omitted")
|
|
47 self.add_argument("command",
|
|
48 help="command to run")
|
|
49 self.options = None
|
|
50 self._hosts = None
|
|
51
|
|
52 def parse_args(self, *args, **kw):
|
|
53 options = argparse.ArgumentParser.parse_args(self, *args, **kw)
|
|
54 self.validate(options)
|
|
55 self.options = options
|
|
56 return options
|
|
57
|
|
58 def validate(self, options):
|
|
59 """validate options"""
|
|
60
|
|
61 def hosts(self):
|
|
62 if self._hosts is None:
|
|
63 assert self.options is not None
|
|
64 self._hosts = self.options.hosts or sys.stdin.read().strip().split()
|
|
65 return self._hosts
|
|
66
|
|
67 def command(self):
|
|
68 return self.options.command
|
|
69
|
|
70 def main(args=sys.argv[1:]):
|
|
71 """CLI"""
|
|
72
|
|
73 # parse command line options
|
|
74 parser = RunCmdParser()
|
|
75 options = parser.parse_args(args)
|
|
76
|
|
77 # get command to run
|
|
78 command = parser.command()
|
|
79
|
|
80 # call the command on all hosts
|
|
81 for host in parser.hosts():
|
|
82 ssh_call(host, command)
|
|
83
|
|
84
|
|
85 if __name__ == '__main__':
|
|
86 main()
|
|
87
|
|
88
|