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