Skip to content
This repository has been archived by the owner on Mar 25, 2018. It is now read-only.

Commit

Permalink
Changed examples to use ComputeService.
Browse files Browse the repository at this point in the history
  • Loading branch information
Everett Toews committed Oct 12, 2012
1 parent 65c005f commit e2a6b7a
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 286 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ atlassian-ide-plugin.xml
*.iws
*.class
rackspace/lib/
rackspace/bin/
lein
project.clj
.lein-deps-sum
41 changes: 21 additions & 20 deletions rackspace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,28 @@ Example code that uses jclouds to perform common tasks on the Rackspace open clo

## Requirements

1. Username and API key for the Rackspace open cloud - See the [Getting Started guide](http://www.jclouds.org/documentation/quickstart/rackspace/)
1. Java Development Kit (JDK) version 6 or later - [Download](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
2. Git - [Download](http://git-scm.com/downloads) or you can just [download this repository as a zip or tar.gz](https://github.com/jclouds/jclouds-examples/downloads)
1. Username and API key for the Rackspace open cloud - See the [Getting Started guide](http://www.jclouds.org/documentation/quickstart/rackspace/).
1. Java Development Kit (JDK) version 6 or later - [Download](http://www.oracle.com/technetwork/java/javase/downloads/index.html).
1. Apache Ant - [Download](http://ant.apache.org/bindownload.cgi).
1. Git - [Download](http://git-scm.com/downloads) or you can just [download this repository as a zip or tar.gz](https://github.com/jclouds/jclouds-examples/downloads).

## Environment
To setup an environment to compile and run the examples follow these instructions.
To setup an environment to compile and run the examples use these commands:

```
git clone https://github.com/jclouds/jclouds-examples.git
cd jcloud-examples/rackspace/
```
Now follow the instructions for [Getting the latest jclouds binaries](http://www.jclouds.org/documentation/userguide/installation-guide/). When you are done you should have a directory with the following files and sub-directories.
Now follow the instructions for [Getting the binaries using Apache Ant](http://www.jclouds.org/documentation/userguide/installation-guide/). When you are done you should have a directory with the following files and sub-directories.

```
$ pwd
/Users/username/jclouds-examples/rackspace
$ ls
README.md images/ lein lib/ project.clj src/
build.xml maven-ant-tasks.jar README.md images/ lib/ src/
```
If you want to run the [Logging example](https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/Logging.java) (which is strongly encouraged!) then you'll need the Logback JAR files. [Download](http://logback.qos.ch/download.html) the zip or tar.gz file, extract, and drop the JARs into the lib directory.
If you chose an installation method other than Ant and you want to run the [Logging example](https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/Logging.java) (which is strongly encouraged!) then you'll need to manually download the Logback JAR files. [Download](http://logback.qos.ch/download.html) the zip or tar.gz file, extract, and drop the JARs into the lib directory.

If you don't, you'll see this error when you try to run the Logging example but the example will still work.

Expand All @@ -37,8 +38,8 @@ SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further detail

Start with the [rackspace package](https://github.com/jclouds/jclouds-examples/tree/master/rackspace/src/main/java/org/jclouds/examples/rackspace). There you will find general purpose examples of things that are useful across all services.

* [Logging](https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/Logging.java) - How to enable and configure logging
* [Authentication](https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/Authentication.java) - How you can use your credentials to authenticate with the Rackspace open cloud
* [Logging](https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/Logging.java) - How to enable and configure logging.
* [Authentication](https://github.com/jclouds/jclouds-examples/blob/master/rackspace/src/main/java/org/jclouds/examples/rackspace/Authentication.java) - How you can use your credentials to authenticate with the Rackspace open cloud.

The [cloudfiles package](https://github.com/jclouds/jclouds-examples/tree/master/rackspace/src/main/java/org/jclouds/examples/rackspace/cloudfiles) demonstrates how to accomplish common tasks for putting files in and getting files from the cloud.

Expand All @@ -52,7 +53,7 @@ The [cloudservers package](https://github.com/jclouds/jclouds-examples/tree/mast


## Command Line
To run these examples from the command line follow these instructions.
To run these examples from the command line use these commands:

```
cd src/main/java/
Expand Down Expand Up @@ -81,11 +82,11 @@ This should create a project with the following Java Settings. Eclipse will have

Try out an example.

1. Double click CreateContainer example file to open it
1. Choose the Run > Run Configurations... menu item
1. Press the plus icon to create a new launch configuration
1. This will automatically create a launch configuration for CreateContainer
1. Switch to the Arguments tab and enter your username and API key in the Program arguments field
1. Double click CreateContainer example file to open it.
1. Choose the Run > Run Configurations... menu item.
1. Press the plus icon to create a new launch configuration.
1. This will automatically create a launch configuration for CreateContainer.
1. Switch to the Arguments tab and enter your username and API key in the Program arguments field.

![Eclipse: Launch Config](https://raw.github.com/jclouds/jclouds-examples/master/rackspace/images/Eclipse3.png "Eclipse: Launch Config")

Expand All @@ -95,11 +96,11 @@ Click Run and watch the Console for the output!

Some suggestions.

1. Change the examples to do different things that you want to do
1. After running some examples, compare the output with what you see in the [Cloud Control Panel](https://mycloud.rackspace.com/)
1. Browse the [documentation](http://www.jclouds.org/documentation/) and have a look at the [Javadoc](http://www.jclouds.org/documentation/releasenotes/) (choose the Javadoc for the current version)
1. Return to the [Installation Guide](http://www.jclouds.org/documentation/userguide/installation-guide/) and have a look at the different ways to integrate jclouds with your project
1. Join the [jclouds mailing list](https://groups.google.com/forum/?fromgroups#!forum/jclouds) or maybe even the [jclouds developer mailing list](https://groups.google.com/forum/?fromgroups#!forum/jclouds-dev)
1. Change the examples to do different things that you want to do.
1. After running some examples, compare the output with what you see in the [Cloud Control Panel](https://mycloud.rackspace.com/).
1. Browse the [documentation](http://www.jclouds.org/documentation/) and have a look at the [Javadoc](http://demobox.github.com/jclouds-maven-site/latest/apidocs).
1. Return to the [Installation Guide](http://www.jclouds.org/documentation/userguide/installation-guide/) and have a look at the different ways to integrate jclouds with your project.
1. Join the [jclouds mailing list](https://groups.google.com/forum/?fromgroups#!forum/jclouds) or maybe even the [jclouds developer mailing list](https://groups.google.com/forum/?fromgroups#!forum/jclouds-dev).

Welcome to the jclouds [community](http://www.jclouds.org/documentation/community/)!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,37 @@

import static org.jclouds.scriptbuilder.domain.Statements.exec;

import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.jclouds.ContextBuilder;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.config.ComputeServiceProperties;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.options.RunScriptOptions;
import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
import org.jclouds.openstack.nova.v2_0.domain.Flavor;
import org.jclouds.openstack.nova.v2_0.domain.Image;
import org.jclouds.openstack.nova.v2_0.domain.Server;
import org.jclouds.openstack.nova.v2_0.domain.Server.Status;
import org.jclouds.openstack.nova.v2_0.domain.ServerCreated;
import org.jclouds.openstack.nova.v2_0.features.FlavorApi;
import org.jclouds.openstack.nova.v2_0.features.ImageApi;
import org.jclouds.openstack.nova.v2_0.features.ServerApi;
import org.jclouds.rest.RestContext;
import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.scriptbuilder.ScriptBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily;
import org.jclouds.sshj.config.SshjSshClientModule;

import com.google.common.base.Throwables;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.net.HostAndPort;
import com.google.inject.Module;

/**
* This example will create a server, start a webserver on it, and publish a page on the internet!
*/
public class CloudServersPublish {
private static final String SERVER_NAME = "jclouds-example-publish";
private static final String ZONE = "DFW";
private static final String USER = "root";
private static final String GROUP_NAME = "jclouds-example";
private static final String LOCATION = "DFW";

private ComputeService compute;
private RestContext<NovaApi, NovaAsyncApi> nova;

/**
* To get a username and API key see http://www.jclouds.org/documentation/quickstart/rackspace/
Expand All @@ -71,8 +63,8 @@ public static void main(String[] args) {

try {
cloudServersPublish.init(args);
Map<String, String> serverInfo = cloudServersPublish.createServer();
cloudServersPublish.configureAndStartWebserver(serverInfo);
NodeMetadata node = cloudServersPublish.createServer();
cloudServersPublish.configureAndStartWebserver(node);
}
catch (Exception e) {
e.printStackTrace();
Expand All @@ -93,45 +85,46 @@ private void init(String[] args) {
Iterable<Module> modules = ImmutableSet.<Module> of(
new SshjSshClientModule());

// These properties control how often jclouds polls for a status udpate
Properties overrides = new Properties();
overrides.setProperty(ComputeServiceProperties.POLL_INITIAL_PERIOD, "20000");
overrides.setProperty(ComputeServiceProperties.POLL_MAX_PERIOD, "20000");

ComputeServiceContext context = ContextBuilder.newBuilder(provider)
.credentials(username, apiKey)
.modules(modules)
.buildView(ComputeServiceContext.class);
compute = context.getComputeService();
nova = context.unwrap();
}

private Map<String, String> createServer() throws RunNodesException, TimeoutException {
String imageId = getImageId();
String flavorId = getFlavorId();

private NodeMetadata createServer() throws RunNodesException, TimeoutException {
Template template = compute.templateBuilder()
.locationId(LOCATION)
.osDescriptionMatches(".*CentOS 6.2.*")
.minRam(512)
.build();

System.out.println("Create Server");

ServerApi serverApi = nova.getApi().getServerApiForZone(ZONE);

ServerCreated serverCreated = serverApi.create(SERVER_NAME, imageId, flavorId);
blockUntilServerInState(serverCreated.getId(), Server.Status.ACTIVE, 600, 5, serverApi);
Server server = serverApi.get(serverCreated.getId());

System.out.println(" " + server);
// This method will continue to poll for the server status and won't return until this server is ACTIVE
// If you want to know what's happening during the polling, enable logging. See
// /jclouds-exmaple/rackspace/src/main/java/org/jclouds/examples/rackspace/Logging.java
Set<? extends NodeMetadata> nodes = compute.createNodesInGroup(GROUP_NAME, 1, template);

NodeMetadata nodeMetadata = nodes.iterator().next();

System.out.println(" " + nodeMetadata);

return ImmutableMap.<String, String> of(
"serverId", server.getId(),
"ip", server.getAccessIPv4(),
"password", serverCreated.getAdminPass());
return nodeMetadata;
}

private void configureAndStartWebserver(Map<String, String> serverInfo) {
private void configureAndStartWebserver(NodeMetadata node) throws TimeoutException {
String publicAddress = node.getPublicAddresses().iterator().next();

System.out.println("Configure And Start Webserver");

// Give ssh 20 seconds to start
try {
Thread.sleep(20 * 1000);
}
catch (InterruptedException e) {
throw Throwables.propagate(e);
}

waitForSsh(publicAddress);

String script = new ScriptBuilder()
.addStatement(exec("yum -y install httpd"))
.addStatement(exec("/usr/sbin/apachectl start"))
Expand All @@ -140,110 +133,21 @@ private void configureAndStartWebserver(Map<String, String> serverInfo) {
.render(OsFamily.UNIX);

RunScriptOptions options = RunScriptOptions.Builder
.overrideLoginUser(USER)
.overrideLoginPassword(serverInfo.get("password"))
.blockOnComplete(true);
compute.runScriptOnNode(ZONE + "/" + serverInfo.get("serverId"), script, options);

System.out.println(" Login IP: " + serverInfo.get("ip") + " Username: " + USER + " Password: " + serverInfo.get("password"));
System.out.println(" Go to http://" + serverInfo.get("ip"));
}

/**
* Will block until the server is in the correct state.
*
* @param serverId The id of the server to block on
* @param status The status the server needs to reach before the method stops blocking
* @param timeoutSeconds The maximum amount of time to block before throwing a TimeoutException
* @param delaySeconds The amout of time between server status checks
* @param serverApi The ServerApi used to do the checking
*
* @throws TimeoutException If the server does not reach the status by timeoutSeconds
*/
protected void blockUntilServerInState(String serverId, Status status,
int timeoutSeconds, int delaySeconds, ServerApi serverApi) throws TimeoutException {
int totalSeconds = 0;

while (totalSeconds < timeoutSeconds) {
System.out.print(".");

Server server = serverApi.get(serverId);

if (server.getStatus().equals(status)) {
System.out.println();
return;
}

try {
Thread.sleep(delaySeconds * 1000);
}
catch (InterruptedException e) {
throw Throwables.propagate(e);
}

totalSeconds += delaySeconds;
}

String message = String.format("Timed out at %d seconds waiting for server %s to reach status %s.",
timeoutSeconds, serverId, status);

throw new TimeoutException(message);
}

/**
* This method uses the generic ComputeService.listHardwareProfiles() to find the hardware profile.
*
* @return The Flavor Id with 512 MB of RAM
*/
private String getFlavorId() {
System.out.println("Flavors");

FlavorApi flavorApi = nova.getApi().getFlavorApiForZone(ZONE);
FluentIterable<? extends Flavor> flavors = flavorApi.listInDetail().concat();
String result = null;
compute.runScriptOnNode(node.getId(), script, options);

for (Flavor flavor: flavors) {
System.out.println(" " + flavor);

if (flavor.getRam() == 512) {
result = flavor.getId();
}
}

if (result == null) {
System.err.println("Flavor with 512 MB of RAM not found. Using first flavor found.");
result = flavors.first().get().getId();
}

return result;
System.out.println(" Login: ssh " + node.getCredentials().getUser() + "@" + publicAddress);
System.out.println(" Password: " + node.getCredentials().getPassword());
System.out.println(" Go to http://" + publicAddress);
}

/**
* This method uses the generic ComputeService.listImages() to find the image.
*
* @return An Ubuntu 12.04 Image
*/
private String getImageId() {
System.out.println("Images");

ImageApi imageApi = nova.getApi().getImageApiForZone(ZONE);
FluentIterable<? extends Image> images = imageApi.listInDetail().concat();
String result = null;

for (Image image: images) {
System.out.println(" " + image);

if ("CentOS 6.3".equals(image.getName())) {
result = image.getId();
}
}

if (result == null) {
System.err.println("Image with CentOS 6.3 operating system not found. Using first image found.");
result = images.first().get().getId();
}

return result;

private void waitForSsh(String ip) throws TimeoutException {
RetryablePredicate<HostAndPort> blockUntilSSHReady = new RetryablePredicate<HostAndPort>(
new InetSocketAddressConnect(), 300, 5, 5, TimeUnit.SECONDS);

if (!blockUntilSSHReady.apply(HostAndPort.fromParts(ip, 22)))
throw new TimeoutException("Timeout on ssh: " + ip);
}

/**
Expand Down
Loading

0 comments on commit e2a6b7a

Please sign in to comment.