forked from jamesyonan/brenda
-
Notifications
You must be signed in to change notification settings - Fork 0
/
brenda-tool
executable file
·133 lines (122 loc) · 6.01 KB
/
brenda-tool
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python
# Brenda -- Render farm tool for Amazon Web Services
# Copyright (C) 2013 James Yonan <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys, optparse
import boto
from brenda import config, error, tool, version, utils
def main():
usage = """\
usage: %s [options] ssh|rsync|instances|perf|prune [args...]
Version:
Brenda %s
Synopsis:
Manage EC2 instances in the render farm.
Commands:
ssh [args...] : run ssh command on all instances and show the output.
rsync [args...] : rsync file(s) to/from all instances, use "HOST" as
a macro for instance hostname.
perf : show performance/cost statistics
instances : show all instances and their uptime.
prune <N_remaining> : kill running instances such that only N_remaining
instances will be retained. Brenda uses a smart
algorithm to decide which instances to kill
(if N_remaining > 0) by selecting instances that
have most recently finished a task to minimize
the amount of lost work.
Command abbreviations:
some brenda-tool commands can be abbreviated by their first letter:
s : ssh
r : rsync
i : instances
Optional config vars:
EC2_REGION : EC2 region name, defaults to US standard (optional).
CREDENTIAL_PROFILE : Profile name to retrieve credentials from
AMI_USER : username for accessing instance.
TOOL_THREADS : max number of simultaneous threads to use when querying
multiple render farm instances (default=64).
REMOTE_PIDFILE : Filename with the process id used on the instance (default="brenda.pid").
Examples:
Copy Brenda configuration file to all running instances:
$ brenda-tool rsync ~/.brenda.conf HOST:
Start render on all instances using config file pushed in previous step:
$ brenda-tool ssh 'brenda-node -D -c .brenda.conf'
View the tail of the log file on each instance:
$ brenda-tool ssh tail log
Run the 'uptime' command on each instance to view CPU utilization:
$ brenda-tool ssh uptime
Enumerate active EC2 instances:
$ brenda-tool instances
Stop the brenda-node script on all instances, but don't shut down the
instances:
$ brenda-tool ssh 'kill $(cat brenda.pid)'
Suppose that you are running a render on 64 instances, the render is almost
(but not quite) complete, and the instances are about to begin their next
billable hour of operation. 64 instances running over the next hour would
be overkill to finish the render job, so you want to scale back the number
of instances to 16:
$ brenda-tool prune 16""" % (sys.argv[0], version.VERSION)
parser = optparse.OptionParser(usage)
parser.disable_interspersed_args()
parser.add_option("-c", "--config", dest="config", default=utils.config_file_name(), metavar="FILE",
help="Configuration file (default: %default)")
parser.add_option("-l", "--logfile", dest="logfile", metavar="FILE",
help="Save log to file")
parser.add_option("-v", "--loglevel", dest="loglevel",
help="Level of events to log (default: INFO)")
parser.add_option("-u", "--user", dest="user",
help="Username for accessing instance, overrides environmental variable AMI_USER")
parser.add_option("-n", "--host", dest="host",
help="ssh/rsync on specific host")
parser.add_option("-H", "--hosts-file", dest="hosts_file", metavar="FILE",
help="ssh/rsync on hosts listed in file")
parser.add_option("-t", "--threshold", type="int", dest="threshold", default=0,
help="Match only on instances whose uptime is > n minutes after the hour, default=%default")
parser.add_option("-m", "--imatch", action="append", dest="imatch", metavar="TYPE",
help="Match only on specific instance types. Option can be specified multiple times.")
parser.add_option("--tag", action="append", nargs=2, dest="tags", metavar="KEY VALUE", default=[("Stack","brenda-render")],
help="Match on specific tags. Option can be specified multiple times.")
parser.add_option("-T", "--terminate", action="store_true", dest="terminate",
help="For prune, terminate instances instead of stopping them (required for AWS spot instances)")
parser.add_option("-d", "--dry-run", action="store_true", dest="dry_run",
help="For prune, show what would be done without actually doing it")
# Get command line arguments...
( opts, args ) = parser.parse_args()
# print "OPTS", (opts, args)
if not args:
print >>sys.stderr, "no work, run with -h for usage"
sys.exit(2)
# Get configuration
conf = config.Config(opts.config, 'BRENDA_')
# print "CONFIG", conf
utils.setup_logger(opts, conf)
# dispatch
if args[0] == 'instances' or args[0] == 'i':
tool.instances(opts, conf)
elif args[0] == 'ssh' or args[0] == 's':
tool.ssh(opts, conf, args[1:])
elif args[0] == 'rsync' or args[0] == 'r':
tool.rsync(opts, conf, args[1:])
elif args[0] == 'prune':
tool.prune(opts, conf, args[1:])
elif args[0] == 'perf':
tool.perf(opts, conf, args[1:])
else:
print >>sys.stderr, "unrecognized command:", args[0]
sys.exit(2)
try:
main()
except boto.exception.EC2ResponseError as e:
error.handle_dry_run(e)