1 import os
2 import sys
3 import time
4 import signal
5 from starcluster import node
6 from starcluster import cluster
7 from starcluster import optcomplete
8 from starcluster.logger import log
9
10
11 -class CmdBase(optcomplete.CmdComplete):
12 """
13 Base class for StarCluster commands
14
15 Each command consists of a class, which has the following properties:
16
17 - Must have a class member 'names' which is a list of the names for
18 the command
19
20 - Can optionally define an addopts(self, parser) method which adds options
21 to the given parser. This defines the command's options.
22 """
23 parser = None
24 opts = None
25 gopts = None
26 gparser = None
27 subcmds_map = None
28 _cfg = None
29 _ec2 = None
30 _s3 = None
31 _cm = None
32 _nm = None
33
34 @property
36 """
37 Property that returns COMP_WORDS from Bash/Zsh completion
38 """
39 return os.environ.get('COMP_WORDS', '').split()
40
41 @property
43 """
44 Returns global options dictionary
45 """
46 return dict(self.gopts.__dict__)
47
48 @property
50 """
51 Returns dictionary of options for this command
52 """
53 return dict(self.opts.__dict__)
54
55 @property
57 """
58 Return only those options with a non-None value
59 """
60 specified = {}
61 options = self.options_dict
62 for opt in options:
63 if options[opt] is not None:
64 specified[opt] = options[opt]
65 return specified
66
67 @property
70
71 @property
73 """
74 Get global StarClusterConfig object
75 """
76 if not self._cfg:
77 self._cfg = self.goptions_dict.get('CONFIG')
78 return self._cfg
79
80 @property
92
93 @property
95 """
96 Returns ClusterManager object configured with self.cfg and self.ec2
97 """
98 if not self._cm:
99 cm = cluster.ClusterManager(self.cfg, ec2=self.ec2)
100 self._cm = cm
101 return self._cm
102
103 cm = cluster_manager
104
105 @property
107 """
108 Returns NodeManager object configured with self.cfg and self.ec2
109 """
110 if not self._nm:
111 nm = node.NodeManager(self.cfg, ec2=self.ec2)
112 self._nm = nm
113 return self._nm
114
115 nm = node_manager
116
117 @property
122
125
127 """
128 Exits program with return value of 1
129 """
130 print
131 log.info("Exiting...")
132 sys.exit(1)
133
135 """
136 Catch ctrl-c interrupt
137 """
138 handler = handler or self.cancel_command
139 signal.signal(signal.SIGINT, handler)
140
142 """
143 Warn user that an experimental feature is being used
144 Counts down from num_secs before continuing
145 """
146 sep = '*' * 60
147 log.warn('\n'.join([sep, msg, sep]), extra=dict(__textwrap__=True))
148 r = range(1, num_secs + 1)
149 r.reverse()
150 print
151 log.warn("Waiting %d seconds before continuing..." % num_secs)
152 log.warn("Press CTRL-C to cancel...")
153 for i in r:
154 sys.stdout.write('%d...' % i)
155 sys.stdout.flush()
156 time.sleep(1)
157 print
158
160 if value <= 0:
161 parser.error("option %s must be a positive integer" % opt_str)
162 setattr(parser.values, option.dest, value)
163
164 - def _build_dict(self, option, opt_str, value, parser):
165 tagdict = getattr(parser.values, option.dest)
166 tags = value.split(',')
167 for tag in tags:
168 tagparts = tag.split('=')
169 key = tagparts[0]
170 if not key:
171 continue
172 value = None
173 if len(tagparts) == 2:
174 value = tagparts[1]
175 tagstore = tagdict.get(key)
176 if isinstance(tagstore, basestring) and value:
177 tagstore = [tagstore, value]
178 elif isinstance(tagstore, list) and value:
179 tagstore.append(value)
180 else:
181 tagstore = value
182 tagdict[key] = tagstore
183 setattr(parser.values, option.dest, tagdict)
184