1
2
3 import time
4
5 from starcluster import static
6 from starcluster import exception
7 from starcluster import optcomplete
8 from starcluster.templates import user_msgs
9 from starcluster.logger import log
10
11 from completers import ClusterCompleter
12
13
15 """
16 start [options] <cluster_tag>
17
18 Start a new cluster
19
20 Example:
21
22 $ starcluster start mynewcluster
23
24 This will launch a cluster named "mynewcluster" using the settings from
25 the default cluster template defined in the configuration file. The
26 default cluster template is specified by the 'default_template' option in
27 the [global] section of the config. To use another template besides the
28 default use the -c (--cluster-template) option:
29
30 $ starcluster start -c largecluster mynewcluster
31
32 This will launch a cluster named "mynewcluster" using the settings from
33 the "largecluster" cluster template instead of the default template.
34 """
35 names = ['start']
36
37 tag = None
38
40 templates = []
41 if self.cfg:
42 templates = self.cfg.get_cluster_names().keys()
43 parser.add_option("-x", "--no-create", dest="no_create",
44 action="store_true", default=False,
45 help="do not launch new EC2 instances when " + \
46 "starting cluster (use existing instances instead)")
47 parser.add_option("-o", "--create-only", dest="create_only",
48 action="store_true", default=False,
49 help="only launch/start EC2 instances, " + \
50 "do not perform any setup routines")
51 parser.add_option("-v", "--validate-only", dest="validate_only",
52 action="store_true", default=False,
53 help="only validate cluster settings, do " + \
54 "not start a cluster")
55 parser.add_option("-V", "--skip-validation", dest="validate",
56 action="store_false", default=True,
57 help="do not validate cluster settings")
58 parser.add_option("-l", "--login-master", dest="login_master",
59 action="store_true", default=False,
60 help="login to master node after launch")
61 parser.add_option("-q", "--disable-queue", dest="disable_queue",
62 action="store_true", default=None,
63 help="do not configure a queueing system (SGE)")
64 parser.add_option("--force-spot-master",
65 dest="force_spot_master", action="store_true",
66 default=None, help="when creating a spot cluster "
67 "the default is to launch the master as "
68 "a flat-rate instance for stability. this option "
69 "forces launching the master node as a spot "
70 "instance when a spot cluster is requested.")
71 opt = parser.add_option("-c", "--cluster-template", action="store",
72 dest="cluster_template", choices=templates,
73 default=None, help="cluster template to use "
74 "from the config file")
75 if optcomplete:
76 opt.completer = optcomplete.ListCompleter(opt.choices)
77 parser.add_option("-r", "--refresh-interval", dest="refresh_interval",
78 type="int", action="callback", default=None,
79 callback=self._positive_int,
80 help="refresh interval when waiting for cluster " + \
81 "nodes to come up (default: 30)")
82 parser.add_option("-b", "--bid", dest="spot_bid", action="store",
83 type="float", default=None,
84 help="requests spot instances instead of flat " + \
85 "rate instances. Uses SPOT_BID as max bid for " + \
86 "the request.")
87 parser.add_option("-d", "--description", dest="cluster_description",
88 action="store", type="string",
89 default="Cluster requested at %s" % \
90 time.strftime("%Y%m%d%H%M"),
91 help="brief description of cluster")
92 parser.add_option("-s", "--cluster-size", dest="cluster_size",
93 action="callback", type="int", default=None,
94 callback=self._positive_int,
95 help="number of ec2 instances to launch")
96 parser.add_option("-u", "--cluster-user", dest="cluster_user",
97 action="store", type="string", default=None,
98 help="name of user to create on cluster " + \
99 "(defaults to sgeadmin)")
100 opt = parser.add_option("-S", "--cluster-shell", dest="cluster_shell",
101 action="store",
102 choices=static.AVAILABLE_SHELLS.keys(),
103 default=None,
104 help="shell for cluster user " + \
105 "(defaults to bash)")
106 if optcomplete:
107 opt.completer = optcomplete.ListCompleter(opt.choices)
108 parser.add_option("-m", "--master-image-id", dest="master_image_id",
109 action="store", type="string", default=None,
110 help="AMI to use when launching master")
111 parser.add_option("-n", "--node-image-id", dest="node_image_id",
112 action="store", type="string", default=None,
113 help="AMI to use when launching nodes")
114 parser.add_option("-I", "--master-instance-type",
115 dest="master_instance_type", action="store",
116 choices=static.INSTANCE_TYPES.keys(), default=None,
117 help="instance type for the master instance")
118 opt = parser.add_option("-i", "--node-instance-type",
119 dest="node_instance_type", action="store",
120 choices=static.INSTANCE_TYPES.keys(),
121 default=None,
122 help="instance type for the node instances")
123 if optcomplete:
124 opt.completer = optcomplete.ListCompleter(opt.choices)
125 parser.add_option("-a", "--availability-zone",
126 dest="availability_zone", action="store",
127 type="string", default=None,
128 help="availability zone to launch instances in")
129 parser.add_option("-k", "--keyname", dest="keyname", action="store",
130 type="string", default=None,
131 help="name of the keypair to use when "
132 "launching the cluster")
133 parser.add_option("-K", "--key-location", dest="key_location",
134 action="store", type="string", default=None,
135 metavar="FILE",
136 help="path to an ssh private key that matches the "
137 "cluster keypair")
138
141
143 if len(args) != 1:
144 self.parser.error("please specify a <cluster_tag>")
145 tag = self.tag = args[0]
146 create = not self.opts.no_create
147 create_only = self.opts.create_only
148 scluster = self.cm.get_cluster_or_none(tag)
149 validate = self.opts.validate
150 validate_running = self.opts.no_create
151 validate_only = self.opts.validate_only
152 if scluster and create:
153 stopped_ebs = scluster.is_cluster_stopped()
154 is_ebs = False
155 if not stopped_ebs:
156 is_ebs = scluster.is_ebs_cluster()
157 raise exception.ClusterExists(tag, is_ebs=is_ebs,
158 stopped_ebs=stopped_ebs)
159 if not scluster and not create:
160 raise exception.ClusterDoesNotExist(tag)
161 elif scluster:
162 validate_running = True
163 else:
164 template = self.opts.cluster_template
165 if not template:
166 try:
167 template = self.cm.get_default_cluster_template()
168 except exception.NoDefaultTemplateFound, e:
169 try:
170 ctmpl = e.options[0]
171 except IndexError:
172 ctmpl = "smallcluster"
173 e.msg += " \n\nAlternatively, you can specify a cluster "
174 e.msg += "template to use by passing the '-c' option to "
175 e.msg += "the 'start' command, e.g.:\n\n"
176 e.msg += " $ starcluster start -c %s %s" % (ctmpl, tag)
177 raise e
178 log.info("Using default cluster template: %s" % template)
179 scluster = self.cm.get_cluster_template(template, tag)
180 scluster.update(self.specified_options_dict)
181 if not self.opts.refresh_interval:
182 interval = self.cfg.globals.get("refresh_interval")
183 scluster.refresh_interval = interval
184 if self.opts.spot_bid is not None and not self.opts.no_create:
185 msg = user_msgs.spotmsg % {'size': scluster.cluster_size,
186 'tag': tag}
187 if not validate_only and not create_only:
188 self.warn_experimental(msg, num_secs=5)
189 self.catch_ctrl_c()
190 scluster.start(create=create, create_only=create_only,
191 validate=validate, validate_only=validate_only,
192 validate_running=validate_running)
193 if validate_only:
194 return
195 if not create_only and not self.opts.login_master:
196 log.info(user_msgs.cluster_started_msg %
197 dict(tag=scluster.cluster_tag),
198 extra=dict(__textwrap__=True, __raw__=True))
199 if self.opts.login_master:
200 scluster.ssh_to_master()
201