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