1 /**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.jclouds.compute;
20
21 import java.util.Map;
22 import java.util.NoSuchElementException;
23 import java.util.Set;
24
25 import org.jclouds.compute.callables.ScriptStillRunningException;
26 import org.jclouds.compute.domain.ComputeMetadata;
27 import org.jclouds.compute.domain.ExecResponse;
28 import org.jclouds.compute.domain.Hardware;
29 import org.jclouds.compute.domain.Image;
30 import org.jclouds.compute.domain.NodeMetadata;
31 import org.jclouds.compute.domain.Template;
32 import org.jclouds.compute.domain.TemplateBuilder;
33 import org.jclouds.compute.internal.BaseComputeService;
34 import org.jclouds.compute.options.RunScriptOptions;
35 import org.jclouds.compute.options.TemplateOptions;
36 import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
37 import org.jclouds.domain.Location;
38 import org.jclouds.io.Payload;
39 import org.jclouds.scriptbuilder.domain.Statement;
40
41 import com.google.common.annotations.Beta;
42 import com.google.common.base.Predicate;
43 import com.google.common.util.concurrent.ListenableFuture;
44 import com.google.inject.ImplementedBy;
45
46 /**
47 * Provides portable access to launching compute instances.
48 *
49 * @author Adrian Cole
50 * @author Ivan Meredith
51 */
52 @ImplementedBy(BaseComputeService.class)
53 public interface ComputeService {
54
55 /**
56 * @return a reference to the context that created this ComputeService.
57 */
58 ComputeServiceContext getContext();
59
60 /**
61 * Makes a new template builder for this service
62 */
63 TemplateBuilder templateBuilder();
64
65 /**
66 * Makes a new set of options for running nodes
67 */
68 TemplateOptions templateOptions();
69
70 /**
71 * The list hardware profiles command shows you the options including virtual cpu count, memory,
72 * and disks. cpu count is not a portable quantity across clouds, as they are measured
73 * differently. However, it is a good indicator of relative speed within a cloud. memory is
74 * measured in megabytes and disks in gigabytes.
75 *
76 * @return a map of hardware profiles by ID, conceding that in some clouds the "id" is not used.
77 */
78 Set<? extends Hardware> listHardwareProfiles();
79
80 /**
81 * Images define the operating system and metadata related to a node. In some clouds, Images are
82 * bound to a specific region, and their identifiers are different across these regions. For this
83 * reason, you should consider matching image requirements like operating system family with
84 * TemplateBuilder as opposed to choosing an image explicitly. The getImages() command returns a
85 * map of images by id.
86 */
87 Set<? extends Image> listImages();
88
89 /**
90 * all nodes available to the current user by id. If possible, the returned set will include
91 * {@link NodeMetadata} objects.
92 */
93 Set<? extends ComputeMetadata> listNodes();
94
95 /**
96 * The list locations command returns all the valid locations for nodes. A location has a scope,
97 * which is typically region or zone. A region is a general area, like eu-west, where a zone is
98 * similar to a datacenter. If a location has a parent, that implies it is within that location.
99 * For example a location can be a rack, whose parent is likely to be a zone.
100 */
101 Set<? extends Location> listAssignableLocations();
102
103 /**
104 *
105 * The compute api treats nodes as a group based on the name you specify. Using this group, you
106 * can choose to operate one or many nodes as a logical unit without regard to the implementation
107 * details of the cloud.
108 * <p/>
109 *
110 * The set that is returned will include credentials you can use to ssh into the nodes. The "key"
111 * part of the credentials is either a password or a private key. You have to inspect the value
112 * to determine this.
113 *
114 * <pre>
115 * if (node.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
116 * // it is a private key, not a password.
117 * </pre>
118 *
119 * <p/>
120 * Note. if all you want to do is execute a script at bootup, you should consider use of the
121 * runscript option.
122 * <p/>
123 * If resources such as security groups are needed, they will be reused or created for you.
124 * Inbound port 22 will always be opened up.
125 *
126 * @param group
127 * - common identifier to group nodes by, cannot contain hyphens
128 * @param count
129 * - how many to fire up.
130 * @param template
131 * - how to configure the nodes
132 * @return all of the nodes the api was able to launch in a running state.
133 *
134 * @throws RunNodesException
135 * when there's a problem applying options to nodes. Note that successful and failed
136 * nodes are a part of this exception, so be sure to inspect this carefully.
137 */
138 Set<? extends NodeMetadata> createNodesInGroup(String group, int count, Template template) throws RunNodesException;
139
140 /**
141 * Like {@link ComputeService#createNodesInGroup(String,int,Template)}, except that the template
142 * is default, equivalent to {@code templateBuilder().any().options(templateOptions)}.
143 */
144 Set<? extends NodeMetadata> createNodesInGroup(String group, int count, TemplateOptions templateOptions)
145 throws RunNodesException;
146
147 /**
148 * Like {@link ComputeService#createNodesInGroup(String,int,TemplateOptions)}, except that the
149 * options are default, as specified in {@link ComputeService#templateOptions}.
150 */
151 Set<? extends NodeMetadata> createNodesInGroup(String group, int count) throws RunNodesException;
152
153 /**
154 * @see #createNodesInGroup(String , int , Template )
155 */
156 @Deprecated
157 Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, Template template) throws RunNodesException;
158
159 /**
160 * @see #createNodesInGroup(String , int , TemplateOptions )
161 */
162 @Deprecated
163 Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, TemplateOptions templateOptions)
164 throws RunNodesException;
165
166 /**
167 * @see #createNodesInGroup(String , int )
168 */
169 @Deprecated
170 Set<? extends NodeMetadata> runNodesWithTag(String tag, int count) throws RunNodesException;
171
172 /**
173 * resume the node from {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state,
174 * given its id.
175 *
176 * <h4>note</h4>
177 *
178 * affected nodes may not resume with the same IP address(es)
179 */
180 void resumeNode(String id);
181
182 /**
183 * nodes matching the filter are treated as a logical set. Using the resume command, you can save
184 * time by resumeing the nodes in parallel.
185 *
186 * <h4>note</h4>
187 *
188 * affected nodes may not resume with the same IP address(es)
189 *
190 * @throws UnsupportedOperationException
191 * if the underlying provider doesn't support suspend/resume
192 * @throws NoSuchElementException
193 * if no nodes matched the predicate specified
194 */
195 void resumeNodesMatching(Predicate<NodeMetadata> filter);
196
197 /**
198 * suspend the node, given its id. This will result in
199 * {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state.
200 *
201 * <h4>note</h4>
202 *
203 * affected nodes may not resume with the same IP address(es)
204 *
205 * @throws UnsupportedOperationException
206 * if the underlying provider doesn't support suspend/resume
207 */
208 void suspendNode(String id);
209
210 /**
211 * nodes matching the filter are treated as a logical set. Using the suspend command, you can
212 * save time by suspending the nodes in parallel.
213 *
214 * <h4>note</h4>
215 *
216 * affected nodes may not resume with the same IP address(es)
217 *
218 * @throws UnsupportedOperationException
219 * if the underlying provider doesn't support suspend/resume
220 * @throws NoSuchElementException
221 * if no nodes matched the predicate specified
222 */
223 void suspendNodesMatching(Predicate<NodeMetadata> filter);
224
225 /**
226 * destroy the node, given its id. If it is the only node in a tag set, the dependent resources
227 * will also be destroyed.
228 */
229 void destroyNode(String id);
230
231 /**
232 * nodes matching the filter are treated as a logical set. Using the delete command, you can save
233 * time by removing the nodes in parallel. When the last node in a set is destroyed, any indirect
234 * resources it uses, such as keypairs, are also destroyed.
235 *
236 * @return list of nodes destroyed
237 */
238 Set<? extends NodeMetadata> destroyNodesMatching(Predicate<NodeMetadata> filter);
239
240 /**
241 * reboot the node, given its id.
242 */
243 void rebootNode(String id);
244
245 /**
246 * nodes matching the filter are treated as a logical set. Using this command, you can save time
247 * by rebooting the nodes in parallel.
248 *
249 * @throws NoSuchElementException
250 * if no nodes matched the predicate specified
251 */
252 void rebootNodesMatching(Predicate<NodeMetadata> filter);
253
254 /**
255 * Find a node by its id.
256 */
257 NodeMetadata getNodeMetadata(String id);
258
259 /**
260 * get all nodes including details such as image and ip addresses even if it incurs extra
261 * requests to the service.
262 *
263 * @param filter
264 * how to select the nodes you are interested in details on.
265 */
266 Set<? extends NodeMetadata> listNodesDetailsMatching(Predicate<ComputeMetadata> filter);
267
268 /**
269 * @see org.jclouds.io.Payloads
270 * @see ComputeService#runScriptOnNodesMatching(Predicate, Statement, RunScriptOptions)
271 */
272 @Deprecated
273 Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript)
274 throws RunScriptOnNodesException;
275
276 /**
277 * @see org.jclouds.io.Payloads
278 * @see ComputeService#runScriptOnNodesMatching(Predicate, Statement, RunScriptOptions)
279 */
280 @Deprecated
281 Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
282 Payload runScript, RunScriptOptions options) throws RunScriptOnNodesException;
283
284 /**
285 *
286 * @see ComputeService#runScriptOnNodesMatching(Predicate, Statement, RunScriptOptions)
287 */
288 Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript)
289 throws RunScriptOnNodesException;
290
291 /**
292 *
293 * @see ComputeService#runScriptOnNodesMatching(Predicate, Statement, RunScriptOptions)
294 */
295 Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
296 Statement runScript) throws RunScriptOnNodesException;
297
298 /**
299 *
300 * @see ComputeService#runScriptOnNodesMatching(Predicate, Statement, RunScriptOptions)
301 */
302 Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, String runScript,
303 RunScriptOptions options) throws RunScriptOnNodesException;
304
305 /**
306 * Run the script on all nodes with the specific predicate.
307 *
308 * @param filter
309 * Predicate-based filter to define on which nodes the script is to be executed
310 * @param runScript
311 * statement containing the script to run
312 * @param options
313 * nullable options to how to run the script, whether to override credentials
314 * @return map with node identifiers and corresponding responses
315 * @throws NoSuchElementException
316 * if no nodes matched the predicate specified
317 * @throws RunScriptOnNodesException
318 * if anything goes wrong during script execution
319 *
320 * @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
321 * @see org.jclouds.scriptbuilder.domain.Statements
322 */
323 Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
324 Statement runScript, RunScriptOptions options) throws RunScriptOnNodesException;
325
326 /**
327 * Run the script on a specific node
328 *
329 * @param id
330 * node the script is to be executed on
331 * @param runScript
332 * statement containing the script to run
333 * @param options
334 * nullable options to how to run the script, whether to override credentials
335 * @return map with node identifiers and corresponding responses
336 * @throws NoSuchElementException
337 * if the node is not found
338 * @throws IllegalStateException
339 * if the node is not in running state
340 * @throws ScriptStillRunningException
341 * if the script was still running after {@link Timeouts#scriptComplete}
342 *
343 * @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
344 * @see org.jclouds.scriptbuilder.domain.Statements
345 */
346 ExecResponse runScriptOnNode(String id, Statement runScript, RunScriptOptions options);
347
348 /**
349 * Run the script on a specific node in the background, typically as {@code nohup}
350 *
351 * @param id
352 * node the script is to be executed on
353 * @param runScript
354 * statement containing the script to run
355 * @param options
356 * nullable options to how to run the script, whether to override credentials
357 * @return map with node identifiers and corresponding responses
358 * @throws NoSuchElementException
359 * if the node is not found
360 * @throws IllegalStateException
361 * if the node is not in running state
362 *
363 * @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
364 * @see org.jclouds.scriptbuilder.domain.Statements
365 */
366 @Beta
367 ListenableFuture<ExecResponse> submitScriptOnNode(String id, Statement runScript, RunScriptOptions options);
368
369 /**
370 * @see #runScriptOnNode(String, Statement, RunScriptOptions)
371 */
372 ExecResponse runScriptOnNode(String id, Statement runScript);
373
374 /**
375 * @see #runScriptOnNode(String, Statement, RunScriptOptions)
376 * @see org.jclouds.scriptbuilder.domain.Statements#exec
377 */
378 ExecResponse runScriptOnNode(String id, String runScript, RunScriptOptions options);
379
380 /**
381 * @see #runScriptOnNode(String, String, RunScriptOptions)
382 */
383 ExecResponse runScriptOnNode(String id, String runScript);
384
385 }