mirror of
https://github.com/apache/jclouds.git
synced 2025-02-16 15:08:28 +00:00
Issue 29: example of how to create/destroy a lamp server
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2556 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
f27950205a
commit
093d1ce393
24
aws/demos/createlamp/.project
Normal file
24
aws/demos/createlamp/.project
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>jclouds-aws-demo-createlamp</name>
|
||||||
|
<comment>jclouds ec2 sample that creates an instance and all you need to access it</comment>
|
||||||
|
<projects>
|
||||||
|
<project>jclouds-aws</project>
|
||||||
|
<project>jclouds-blobstore</project>
|
||||||
|
<project>jclouds-core</project>
|
||||||
|
<project>jclouds-jsch</project>
|
||||||
|
<project>jclouds-log4j</project>
|
||||||
|
<project>jclouds-scriptbuilder</project>
|
||||||
|
<project>resteasy-jaxrs-client</project>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
30
aws/demos/createlamp/README.txt
Executable file
30
aws/demos/createlamp/README.txt
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
====
|
||||||
|
|
||||||
|
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
====================================================================
|
||||||
|
====
|
||||||
|
#
|
||||||
|
# this is a simple example command line client that creates a lamp server and everything you need to do that in ec2
|
||||||
|
# 1. execute 'mvn install' to build the sample
|
||||||
|
# 2. invoke the jar, passing your aws credentials and the name you wish to create or destroy
|
||||||
|
# ex.
|
||||||
|
# java -jar target/jclouds-aws-demo-createlamp-jar-with-dependencies.jar accesskey secretkey create adrianalmighty
|
||||||
|
# java -jar target/jclouds-aws-demo-createlamp-jar-with-dependencies.jar accesskey secretkey destroy adrianalmighty
|
83
aws/demos/createlamp/pom.xml
Normal file
83
aws/demos/createlamp/pom.xml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
$HeadURL$ $Revision$ $Date$ Copyright (C) 2009 Cloud Conscious,
|
||||||
|
LLC. <info@cloudconscious.com>
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or
|
||||||
|
more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information regarding
|
||||||
|
copyright ownership. The ASF licenses this file to you under the
|
||||||
|
Apache License, Version 2.0 (the "License"); you may not use
|
||||||
|
this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0.html Unless required
|
||||||
|
by applicable law or agreed to in writing, software distributed
|
||||||
|
under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions
|
||||||
|
and limitations under the License.
|
||||||
|
====================================================================
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-aws-demos-project</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>jclouds-aws-demo-createlamp</artifactId>
|
||||||
|
<name>jclouds ec2 sample that creates an instance and all you need to access it</name>
|
||||||
|
<description>jclouds ec2 sample that creates an instance and all you need to access it</description>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-scriptbuilder</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>org.jclouds.aws.ec2.demos.createlamp.MainApp</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>org.jclouds.aws.ec2.demos.createlamp.MainApp</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,254 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.aws.ec2.demos.createlamp;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType;
|
||||||
|
import static org.jclouds.scriptbuilder.domain.Statements.exec;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||||
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
import org.jclouds.aws.ec2.EC2ContextFactory;
|
||||||
|
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||||
|
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||||
|
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||||
|
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||||
|
import org.jclouds.aws.ec2.domain.Region;
|
||||||
|
import org.jclouds.aws.ec2.domain.Reservation;
|
||||||
|
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||||
|
import org.jclouds.aws.ec2.predicates.InstanceStateRunning;
|
||||||
|
import org.jclouds.encryption.internal.Base64;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.predicates.SocketOpen;
|
||||||
|
import org.jclouds.rest.RestContext;
|
||||||
|
import org.jclouds.scriptbuilder.ScriptBuilder;
|
||||||
|
import org.jclouds.scriptbuilder.domain.OsFamily;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This the Main class of an Application that demonstrates the use of the EC2Client by creating a
|
||||||
|
* small lamp server.
|
||||||
|
*
|
||||||
|
* Usage is: java MainApp accesskeyid secretkey command name where command in create destroy
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class MainApp {
|
||||||
|
|
||||||
|
public static int PARAMETERS = 4;
|
||||||
|
public static String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: accesskeyid secretkey command name\nwhere command in create destroy";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws TimeoutException {
|
||||||
|
|
||||||
|
if (args.length < PARAMETERS)
|
||||||
|
throw new IllegalArgumentException(INVALID_SYNTAX);
|
||||||
|
|
||||||
|
// Args
|
||||||
|
String accesskeyid = args[0];
|
||||||
|
String secretkey = args[1];
|
||||||
|
String command = args[2];
|
||||||
|
String name = args[3];
|
||||||
|
|
||||||
|
// Init
|
||||||
|
RestContext<EC2AsyncClient, EC2Client> context = EC2ContextFactory.createContext(accesskeyid,
|
||||||
|
secretkey);
|
||||||
|
|
||||||
|
// Get a synchronous client
|
||||||
|
EC2Client client = context.getApi();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (command.equals("create")) {
|
||||||
|
|
||||||
|
KeyPair pair = createKeyPair(client, name);
|
||||||
|
|
||||||
|
RunningInstance instance = createSecurityGroupKeyPairAndInstance(client, name);
|
||||||
|
|
||||||
|
System.out.printf("instance %s ready%n", instance.getId());
|
||||||
|
System.out.printf("ip address: %s%n", instance.getIpAddress().getHostAddress());
|
||||||
|
System.out.printf("dns name: %s%n", instance.getDnsName());
|
||||||
|
System.out.printf("login identity:%n%s%n", pair.getKeyMaterial());
|
||||||
|
|
||||||
|
} else if (command.equals("destroy")) {
|
||||||
|
destroySecurityGroupKeyPairAndInstance(client, name);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(INVALID_SYNTAX);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// Close connecton
|
||||||
|
context.close();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void destroySecurityGroupKeyPairAndInstance(EC2Client client, String name) {
|
||||||
|
try {
|
||||||
|
String id = findInstanceByKeyName(client, name).getId();
|
||||||
|
System.out.printf("%d: %s terminating instance%n", System.currentTimeMillis(), id);
|
||||||
|
client.getInstanceServices().terminateInstancesInRegion(Region.DEFAULT,
|
||||||
|
findInstanceByKeyName(client, name).getId());
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
System.out.printf("%d: %s deleting keypair%n", System.currentTimeMillis(), name);
|
||||||
|
client.getKeyPairServices().deleteKeyPairInRegion(Region.DEFAULT, name);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
System.out.printf("%d: %s deleting group%n", System.currentTimeMillis(), name);
|
||||||
|
client.getSecurityGroupServices().deleteSecurityGroupInRegion(Region.DEFAULT, name);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RunningInstance createSecurityGroupKeyPairAndInstance(EC2Client client,
|
||||||
|
String name) throws TimeoutException {
|
||||||
|
// create a new security group
|
||||||
|
createSecurityGroupAndAuthorizePorts(client, name);
|
||||||
|
|
||||||
|
// create a new instance
|
||||||
|
RunningInstance instance = runInstance(client, name, name);
|
||||||
|
|
||||||
|
// await for the instance to start
|
||||||
|
return blockUntilInstanceRunning(client, instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createSecurityGroupAndAuthorizePorts(EC2Client client, String name) {
|
||||||
|
System.out.printf("%d: creating security group: %s%n", System.currentTimeMillis(), name);
|
||||||
|
client.getSecurityGroupServices().createSecurityGroupInRegion(Region.DEFAULT, name, name);
|
||||||
|
for (int port : new int[] { 80, 443, 22 }) {
|
||||||
|
client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(Region.DEFAULT,
|
||||||
|
name, IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static KeyPair createKeyPair(EC2Client client, String name) {
|
||||||
|
System.out.printf("%d: creating keypair: %s%n", System.currentTimeMillis(), name);
|
||||||
|
return client.getKeyPairServices().createKeyPairInRegion(Region.DEFAULT, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RunningInstance runInstance(EC2Client client, String securityGroupName, String keyPairName) {
|
||||||
|
|
||||||
|
String script = new ScriptBuilder() // lamp install script
|
||||||
|
.addStatement(exec("runurl run.alestic.com/apt/upgrade"))
|
||||||
|
.addStatement(exec("runurl run.alestic.com/install/lamp"))
|
||||||
|
.build(OsFamily.UNIX);
|
||||||
|
|
||||||
|
// userData must be base 64 encoded
|
||||||
|
String encodedScript = Base64.encodeBytes(script.getBytes());
|
||||||
|
|
||||||
|
System.out.printf("%d: running instance%n", System.currentTimeMillis());
|
||||||
|
Reservation reservation = client.getInstanceServices().runInstancesInRegion(Region.DEFAULT,
|
||||||
|
null, // allow ec2 to chose an availability zone
|
||||||
|
"ami-ccf615a5", // alestic ami allows auto-invoke of user data scripts
|
||||||
|
1, // minimum instances
|
||||||
|
1, // maximum instances
|
||||||
|
asType(InstanceType.M1_SMALL) // smallest instance size
|
||||||
|
.withKeyName(keyPairName) // key I created above
|
||||||
|
.withSecurityGroup(securityGroupName) // group I created above
|
||||||
|
.withUserData(encodedScript)); // script to run as root
|
||||||
|
|
||||||
|
return Iterables.getOnlyElement(reservation.getRunningInstances());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static RunningInstance blockUntilInstanceRunning(EC2Client client, RunningInstance instance)
|
||||||
|
throws TimeoutException {
|
||||||
|
// create utilities that wait for the instance to finish
|
||||||
|
RetryablePredicate<RunningInstance> runningTester = new RetryablePredicate<RunningInstance>(
|
||||||
|
new InstanceStateRunning(client.getInstanceServices()), 180, 5, TimeUnit.SECONDS);
|
||||||
|
RetryablePredicate<InetSocketAddress> socketTester = new RetryablePredicate<InetSocketAddress>(
|
||||||
|
new SocketOpen(), 180, 1, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance
|
||||||
|
.getId());
|
||||||
|
if (!runningTester.apply(instance))
|
||||||
|
throw new TimeoutException("timeout waiting for instance to run: " + instance.getId());
|
||||||
|
|
||||||
|
instance = findInstanceById(client, instance.getId());
|
||||||
|
|
||||||
|
System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(),
|
||||||
|
instance.getIpAddress());
|
||||||
|
if (!socketTester.apply(new InetSocketAddress(instance.getIpAddress(), 22)))
|
||||||
|
throw new TimeoutException("timeout waiting for ssh to start: " + instance.getIpAddress());
|
||||||
|
|
||||||
|
System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance
|
||||||
|
.getIpAddress());
|
||||||
|
|
||||||
|
System.out.printf("%d: %s awaiting http service to start%n", System.currentTimeMillis(),
|
||||||
|
instance.getIpAddress());
|
||||||
|
if (!socketTester.apply(new InetSocketAddress(instance.getIpAddress(), 80)))
|
||||||
|
throw new TimeoutException("timeout waiting for http to start: " + instance.getIpAddress());
|
||||||
|
|
||||||
|
System.out.printf("%d: %s http service started%n", System.currentTimeMillis(), instance
|
||||||
|
.getIpAddress());
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RunningInstance findInstanceById(EC2Client client, String instanceId) {
|
||||||
|
// search my account for the instance I just created
|
||||||
|
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(
|
||||||
|
Region.DEFAULT, instanceId); // last parameter (ids) narrows the search
|
||||||
|
|
||||||
|
// since we refined by instanceId there should only be one instance
|
||||||
|
return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations).getRunningInstances());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RunningInstance findInstanceByKeyName(EC2Client client, final String keyName) {
|
||||||
|
// search my account for the instance I just created
|
||||||
|
Set<Reservation> reservations = client.getInstanceServices().describeInstancesInRegion(
|
||||||
|
Region.DEFAULT);
|
||||||
|
|
||||||
|
// extract all the instances from all reservations
|
||||||
|
Set<RunningInstance> allInstances = Sets.newHashSet();
|
||||||
|
for (Reservation reservation : reservations) {
|
||||||
|
allInstances.addAll(reservation.getRunningInstances());
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the first one that has a keyname matching what I just created
|
||||||
|
return Iterables.find(allInstances, new Predicate<RunningInstance>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(RunningInstance input) {
|
||||||
|
return input.getKeyName().equals(keyName)
|
||||||
|
&& input.getInstanceState() != InstanceState.TERMINATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,7 @@
|
|||||||
<!-- as this has a dependency on something you can't get from maven, excluding
|
<!-- as this has a dependency on something you can't get from maven, excluding
|
||||||
<module>googleappengine</module>
|
<module>googleappengine</module>
|
||||||
-->
|
-->
|
||||||
|
<module>createlamp</module>
|
||||||
<module>createandlistbuckets</module>
|
<module>createandlistbuckets</module>
|
||||||
</modules>
|
</modules>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user