Mercurial > hg > KCl
comparison kcl/run_cmd.py @ 0:0f44ee073173 default tip
fake salt, initial commit
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Mon, 06 Feb 2017 01:10:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:0f44ee073173 |
---|---|
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 |