mirror of https://github.com/apache/jclouds.git
resize-ebs is moved to clouddemo repository
This commit is contained in:
parent
6c26047e6a
commit
2ccbc8e40a
|
@ -1,16 +0,0 @@
|
||||||
This demo is used to show how to change volume size for EBS-backed instance. Basically, jclouds API is used to run a sequence of commands, as described in an excellent article: http://alestic.com/2009/12/ec2-ebs-boot-resize.
|
|
||||||
|
|
||||||
There are 2 directories:
|
|
||||||
|
|
||||||
First one, /resize-ebs-java, has all necessary classes for the demo (under org.jclouds.tools.ebsresize), and also a sample Java launcher (EbsResizeMain). Please change the variables in EbsResizeMain to run the demo.
|
|
||||||
|
|
||||||
Second directory, /jruby-client, has a JRuby launcher for the same Java libraries. Please change the variables in launcher.rb to run the demo.
|
|
||||||
To manage the maven dependencies, run as:
|
|
||||||
$ mvn jruby:run
|
|
||||||
|
|
||||||
Pre-requisites:
|
|
||||||
- running EBS-backed instance at Amazon EC2
|
|
||||||
- Ubuntu image
|
|
||||||
- proper settings in place (EbsResizeMain or launcher.rb)
|
|
||||||
- file system is ext3 (otherwise, change is needed in org.jclouds.tools.ebsresize.InstanceVolumeManager)
|
|
||||||
- the demo doesn't take care of freezing the database, filesystem and application data
|
|
|
@ -1,9 +0,0 @@
|
||||||
# use glob syntax.
|
|
||||||
syntax: glob
|
|
||||||
target
|
|
||||||
.settings
|
|
||||||
.classpath
|
|
||||||
.project
|
|
||||||
jclouds-aws-demo-ebsresize-ruby.iml
|
|
||||||
jclouds-aws-demo-ebsresize-ruby.ipr
|
|
||||||
jclouds-aws-demo-ebsresize-ruby.iws
|
|
|
@ -1,66 +0,0 @@
|
||||||
<!--
|
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
|
|
||||||
====================================================================
|
|
||||||
Licensed 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.
|
|
||||||
====================================================================
|
|
||||||
|
|
||||||
-->
|
|
||||||
<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/maven-v4_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-ebsresize-ruby</artifactId>
|
|
||||||
<groupId>org.jclouds</groupId>
|
|
||||||
|
|
||||||
<name>JRuby client for demo to change volume size for EBS-based instances</name>
|
|
||||||
<description>JRuby is used to run jclouds-aws-demo-ebsresize demo</description>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>jclouds</id>
|
|
||||||
<url>http://jclouds.googlecode.com/svn/repo</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>jclouds-snapshot.repository</id>
|
|
||||||
<url>http://jclouds.rimuhosting.com/maven2/snapshots</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.codehaus.mojo</groupId>
|
|
||||||
<artifactId>jruby-maven-plugin</artifactId>
|
|
||||||
<version>1.0-beta-4</version>
|
|
||||||
<configuration>
|
|
||||||
<script>src/main/scripts/launcher.rb</script>
|
|
||||||
</configuration>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jclouds</groupId>
|
|
||||||
<artifactId>jclouds-aws-demo-ebsresize</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
|
@ -1,59 +0,0 @@
|
||||||
=begin
|
|
||||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
|
|
||||||
====================================================================
|
|
||||||
Licensed 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.
|
|
||||||
====================================================================
|
|
||||||
=end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
For more information, refer to:
|
|
||||||
http://alestic.com/2009/12/ec2-ebs-boot-resize
|
|
||||||
=end
|
|
||||||
class EbsVolumesJRuby
|
|
||||||
|
|
||||||
def initialize access_key_id, secret_key
|
|
||||||
@access_key_id = access_key_id
|
|
||||||
@secret_key = secret_key
|
|
||||||
end
|
|
||||||
|
|
||||||
def resize instance_id, region, new_size
|
|
||||||
|
|
||||||
@manager = org.jclouds.tools.ebsresize.InstanceVolumeManager.new(@access_key_id, @secret_key)
|
|
||||||
|
|
||||||
ebs_api = @manager.get_ebs_api
|
|
||||||
instance_api = @manager.get_instance_api
|
|
||||||
api = @manager.get_api
|
|
||||||
|
|
||||||
@instance = instance_api.get_instance_by_id_and_region instance_id, region
|
|
||||||
|
|
||||||
instance_api.stop_instance @instance
|
|
||||||
|
|
||||||
volume = ebs_api.get_root_volume_for_instance @instance
|
|
||||||
|
|
||||||
ebs_api.detach_volume_from_stopped_instance volume, @instance
|
|
||||||
|
|
||||||
new_volume = ebs_api.clone_volume_with_new_size volume, new_size
|
|
||||||
|
|
||||||
ebs_api.attach_volume_to_stopped_instance new_volume, @instance
|
|
||||||
|
|
||||||
instance_api.start_instance @instance
|
|
||||||
|
|
||||||
api.get_elastic_block_store_services().delete_volume_in_region @instance.get_region(), volume.get_id()
|
|
||||||
end
|
|
||||||
|
|
||||||
def run_remote_resize_commands credentials, key_pair
|
|
||||||
@manager.run_remote_resize_commands @instance, credentials, key_pair
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
|
@ -1,38 +0,0 @@
|
||||||
=begin
|
|
||||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
|
|
||||||
====================================================================
|
|
||||||
Licensed 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.
|
|
||||||
====================================================================
|
|
||||||
=end
|
|
||||||
|
|
||||||
require "src/main/scripts/ebs_volumes_j_ruby.rb"
|
|
||||||
|
|
||||||
instance_id = "AMAZON_INSTANCE_ID (i-xxxxxx)"
|
|
||||||
region = org.jclouds.aws.domain.Region::US_EAST_1
|
|
||||||
new_size = 6
|
|
||||||
remote_login = "ubuntu"
|
|
||||||
remote_password = ""
|
|
||||||
path_to_key = ""
|
|
||||||
|
|
||||||
ebs_volumes = EbsVolumesJRuby.new("YOUR_ACCESS_KEY_ID", "YOUR_SECRET_KEY")
|
|
||||||
|
|
||||||
ebs_volumes.resize instance_id, region, new_size
|
|
||||||
|
|
||||||
key_pair = org.jclouds.util.Utils::toStringAndClose(
|
|
||||||
java.io.FileInputStream.new(path_to_key))
|
|
||||||
credentials = org.jclouds.domain.Credentials.new(remote_login, remote_password)
|
|
||||||
|
|
||||||
java.lang.Thread::sleep(25000);
|
|
||||||
|
|
||||||
ebs_volumes.run_remote_resize_commands credentials, key_pair
|
|
|
@ -1,9 +0,0 @@
|
||||||
# use glob syntax.
|
|
||||||
syntax: glob
|
|
||||||
target
|
|
||||||
.settings
|
|
||||||
.classpath
|
|
||||||
.project
|
|
||||||
jclouds-aws-demo-ebsresize.iml
|
|
||||||
jclouds-aws-demo-ebsresize.ipr
|
|
||||||
jclouds-aws-demo-ebsresize.iws
|
|
|
@ -1,66 +0,0 @@
|
||||||
<!--
|
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
|
|
||||||
====================================================================
|
|
||||||
Licensed 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.
|
|
||||||
====================================================================
|
|
||||||
|
|
||||||
-->
|
|
||||||
<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/maven-v4_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-ebsresize</artifactId>
|
|
||||||
<groupId>org.jclouds</groupId>
|
|
||||||
|
|
||||||
<name>jclouds EC2 demo, to change volume size for EBS-based instances</name>
|
|
||||||
<description>For a given running instance, resizes the volume (with several minutes of downtime)</description>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>jclouds</id>
|
|
||||||
<url>http://jclouds.googlecode.com/svn/repo</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>jclouds-snapshot.repository</id>
|
|
||||||
<url>http://jclouds.rimuhosting.com/maven2/snapshots</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jclouds</groupId>
|
|
||||||
<artifactId>jclouds-jsch</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>1.6</source>
|
|
||||||
<target>1.6</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
|
@ -1,59 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed 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.
|
|
||||||
* ====================================================================
|
|
||||||
*/
|
|
||||||
|
|
||||||
import org.jclouds.aws.domain.Region;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.tools.ebsresize.InstanceVolumeManager;
|
|
||||||
import org.jclouds.util.Utils;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launcher for EBS resize demo. This is the Java version of what
|
|
||||||
* can be written in Ruby (see <jclouds>/aws/demos/resize-ebs/jruby-client)
|
|
||||||
*
|
|
||||||
* @author Oleksiy Yarmula
|
|
||||||
*/
|
|
||||||
public class EbsResizeMain {
|
|
||||||
|
|
||||||
String accessKeyId = "YOUR_ACCESS_KEY_ID";
|
|
||||||
String secretKey = "YOUR_SECRET_KEY";
|
|
||||||
String instanceId = "AMAZON_INSTANCE_ID (i-xxxxxx)";
|
|
||||||
Region region = Region.US_EAST_1;
|
|
||||||
int newSize = 6;
|
|
||||||
String pathToKeyPair = "";
|
|
||||||
String remoteLogin = "ubuntu";
|
|
||||||
String remotePassword = "";
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
new EbsResizeMain().launch();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void launch() throws Exception {
|
|
||||||
|
|
||||||
InstanceVolumeManager manager = new InstanceVolumeManager(accessKeyId, secretKey);
|
|
||||||
|
|
||||||
String privateKey =
|
|
||||||
Utils.toStringAndClose(new FileInputStream(pathToKeyPair));
|
|
||||||
|
|
||||||
manager.resizeVolume(instanceId, region, new Credentials(remoteLogin, remotePassword),
|
|
||||||
privateKey, newSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed 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.tools.ebsresize;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.inject.Module;
|
|
||||||
import com.google.inject.internal.ImmutableSet;
|
|
||||||
import org.jclouds.aws.domain.Region;
|
|
||||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
|
||||||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
|
||||||
import org.jclouds.aws.ec2.domain.Volume;
|
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
|
||||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.predicates.SocketOpen;
|
|
||||||
import org.jclouds.rest.RestContext;
|
|
||||||
import org.jclouds.tools.ebsresize.facade.ElasticBlockStoreFacade;
|
|
||||||
import org.jclouds.tools.ebsresize.facade.InstanceFacade;
|
|
||||||
import org.jclouds.tools.ebsresize.util.SshExecutor;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Launches a sequence of commands to change the size of
|
|
||||||
* EBS volume.
|
|
||||||
*
|
|
||||||
* This results in several minutes of downtime of the instance.
|
|
||||||
* More details available at:
|
|
||||||
* <a href="http://alestic.com/2010/02/ec2-resize-running-ebs-root" />
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author Oleksiy Yarmula
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class InstanceVolumeManager {
|
|
||||||
|
|
||||||
private final ComputeServiceContext context;
|
|
||||||
|
|
||||||
@SuppressWarnings({"FieldCanBeLocal"})
|
|
||||||
private final RestContext<EC2AsyncClient, EC2Client> ec2context;
|
|
||||||
private final EC2Client api;
|
|
||||||
private final ElasticBlockStoreFacade ebsApi;
|
|
||||||
private final InstanceFacade instanceApi;
|
|
||||||
private final Predicate<InetSocketAddress> socketOpen =
|
|
||||||
new RetryablePredicate<InetSocketAddress>(new SocketOpen(), 180, 5, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
public InstanceVolumeManager(String accessKeyId, String secretKey) {
|
|
||||||
this(accessKeyId, secretKey, new Properties());
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
InstanceVolumeManager(String accessKeyId, String secretKey, Properties overridesForContext) {
|
|
||||||
try {
|
|
||||||
context = new ComputeServiceContextFactory()
|
|
||||||
.createContext("ec2", accessKeyId, secretKey,
|
|
||||||
ImmutableSet.<Module> of(), overridesForContext);
|
|
||||||
} catch(IOException e) { throw new RuntimeException(e); }
|
|
||||||
|
|
||||||
ec2context = context.getProviderSpecificContext();
|
|
||||||
api = ec2context.getApi();
|
|
||||||
|
|
||||||
ebsApi = new ElasticBlockStoreFacade(api.getElasticBlockStoreServices());
|
|
||||||
instanceApi = new InstanceFacade(api.getInstanceServices());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resizeVolume(String instanceId, Region region,
|
|
||||||
Credentials instanceCredentials, String pathToKeyPair, int newSize) {
|
|
||||||
RunningInstance instance = instanceApi.getInstanceByIdAndRegion(instanceId, region);
|
|
||||||
|
|
||||||
instanceApi.stopInstance(instance);
|
|
||||||
|
|
||||||
Volume volume = ebsApi.getRootVolumeForInstance(instance);
|
|
||||||
|
|
||||||
ebsApi.detachVolumeFromStoppedInstance(volume, instance);
|
|
||||||
|
|
||||||
Volume newVolume = ebsApi.cloneVolumeWithNewSize(volume, newSize);
|
|
||||||
|
|
||||||
ebsApi.attachVolumeToStoppedInstance(newVolume, instance);
|
|
||||||
|
|
||||||
instanceApi.startInstance(instance);
|
|
||||||
|
|
||||||
api.getElasticBlockStoreServices().deleteVolumeInRegion(instance.getRegion(), volume.getId());
|
|
||||||
|
|
||||||
runRemoteResizeCommands(instance, instanceCredentials, pathToKeyPair);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runRemoteResizeCommands(RunningInstance instance, Credentials instanceCredentials,
|
|
||||||
String keyPair) {
|
|
||||||
|
|
||||||
Map<String, ? extends ComputeMetadata> nodes = context.getComputeService().getNodes();
|
|
||||||
|
|
||||||
//if don't set it here, nodeMetadata.getCredentials = null
|
|
||||||
NodeMetadata nodeMetadata = addCredentials((NodeMetadata) nodes.get(instance.getId()),
|
|
||||||
instanceCredentials);
|
|
||||||
|
|
||||||
InetSocketAddress socket =
|
|
||||||
new InetSocketAddress(Iterables.getLast(nodeMetadata.getPublicAddresses()), 22);
|
|
||||||
|
|
||||||
SshExecutor sshExecutor = new SshExecutor(nodeMetadata, instanceCredentials,
|
|
||||||
keyPair, socket);
|
|
||||||
|
|
||||||
waitForSocket(socket);
|
|
||||||
|
|
||||||
sshExecutor.connect();
|
|
||||||
sshExecutor.execute("sudo resize2fs " + instance.getRootDeviceName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private NodeMetadata addCredentials(NodeMetadata nodeMetadata, Credentials credentials) {
|
|
||||||
return new
|
|
||||||
NodeMetadataImpl(nodeMetadata.getId(), nodeMetadata.getName(),
|
|
||||||
nodeMetadata.getLocationId(),
|
|
||||||
nodeMetadata.getUri(),
|
|
||||||
nodeMetadata.getUserMetadata(), nodeMetadata.getTag(),
|
|
||||||
nodeMetadata.getState(), nodeMetadata.getPublicAddresses(),
|
|
||||||
nodeMetadata.getPrivateAddresses(), nodeMetadata.getExtra(),
|
|
||||||
credentials);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void waitForSocket(InetSocketAddress socket) {
|
|
||||||
checkState(socketOpen.apply(socket),
|
|
||||||
/*or throw*/ "Couldn't connect to instance");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeContext() {
|
|
||||||
context.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ElasticBlockStoreFacade getEbsApi() {
|
|
||||||
return ebsApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InstanceFacade getInstanceApi() {
|
|
||||||
return instanceApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EC2Client getApi() {
|
|
||||||
return api;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComputeServiceContext getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,150 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed 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.tools.ebsresize.facade;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import org.jclouds.aws.ec2.domain.*;
|
|
||||||
import org.jclouds.aws.ec2.options.CreateSnapshotOptions;
|
|
||||||
import org.jclouds.aws.ec2.options.DetachVolumeOptions;
|
|
||||||
import org.jclouds.aws.ec2.predicates.SnapshotCompleted;
|
|
||||||
import org.jclouds.aws.ec2.predicates.VolumeAttached;
|
|
||||||
import org.jclouds.aws.ec2.predicates.VolumeAvailable;
|
|
||||||
import org.jclouds.aws.ec2.services.ElasticBlockStoreClient;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Aggregates several methods of jClouds' EC2 functionality
|
|
||||||
* to work with elastic block store.
|
|
||||||
*
|
|
||||||
* @author Oleksiy Yarmula
|
|
||||||
*/
|
|
||||||
public class ElasticBlockStoreFacade {
|
|
||||||
|
|
||||||
final private ElasticBlockStoreClient elasticBlockStoreServices;
|
|
||||||
final private Predicate<Volume> volumeAvailable;
|
|
||||||
final private Predicate<Attachment> volumeAttached;
|
|
||||||
final private Predicate<Snapshot> snapshotCompleted;
|
|
||||||
|
|
||||||
public ElasticBlockStoreFacade(ElasticBlockStoreClient elasticBlockStoreServices) {
|
|
||||||
this.elasticBlockStoreServices = elasticBlockStoreServices;
|
|
||||||
this.volumeAvailable =
|
|
||||||
new RetryablePredicate<Volume>(new VolumeAvailable(elasticBlockStoreServices),
|
|
||||||
600, 10, TimeUnit.SECONDS);
|
|
||||||
this.volumeAttached =
|
|
||||||
new RetryablePredicate<Attachment>(new VolumeAttached(elasticBlockStoreServices),
|
|
||||||
600, 10, TimeUnit.SECONDS);
|
|
||||||
this.snapshotCompleted = new RetryablePredicate<Snapshot>(new SnapshotCompleted(
|
|
||||||
elasticBlockStoreServices), 600, 10, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the root volume for instance with EBS type of root device.
|
|
||||||
*
|
|
||||||
* @param runningInstance
|
|
||||||
* instance of EBS type that has volume(s) attached
|
|
||||||
* @return root device volume
|
|
||||||
*/
|
|
||||||
public Volume getRootVolumeForInstance(RunningInstance runningInstance) {
|
|
||||||
checkArgument(runningInstance.getRootDeviceType() == RootDeviceType.EBS,
|
|
||||||
"Only storage for instances with EBS type of root device can be resized.");
|
|
||||||
|
|
||||||
String rootDevice = checkNotNull(runningInstance.getRootDeviceName());
|
|
||||||
|
|
||||||
//get volume id
|
|
||||||
String volumeId = null;
|
|
||||||
for(String ebsVolumeId : runningInstance.getEbsBlockDevices().keySet()) {
|
|
||||||
if(! rootDevice.equals(ebsVolumeId)) continue;
|
|
||||||
RunningInstance.EbsBlockDevice device = runningInstance.getEbsBlockDevices().get(ebsVolumeId);
|
|
||||||
volumeId = checkNotNull(device.getVolumeId(), "Device's volume id must not be null.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//return volume by volume id
|
|
||||||
return Iterables.getOnlyElement(elasticBlockStoreServices.
|
|
||||||
describeVolumesInRegion(runningInstance.getRegion(), volumeId));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detaches volume from an instance.
|
|
||||||
*
|
|
||||||
* This method blocks until the operations are fully completed.
|
|
||||||
* @param volume
|
|
||||||
* volume to detach
|
|
||||||
* @param stoppedInstance
|
|
||||||
* instance to which the volume is currently attached
|
|
||||||
*/
|
|
||||||
public void detachVolumeFromStoppedInstance(Volume volume, RunningInstance stoppedInstance) {
|
|
||||||
elasticBlockStoreServices.detachVolumeInRegion(stoppedInstance.getRegion(), volume.getId(), false,
|
|
||||||
DetachVolumeOptions.Builder.fromInstance(stoppedInstance.getId()));
|
|
||||||
checkState(volumeAvailable.apply(volume),
|
|
||||||
/*or throw*/ "Couldn't detach the volume from instance");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes a 'copy' of current volume with different size.
|
|
||||||
* Behind the scenes, if creates a snapshot of current volume,
|
|
||||||
* and then creates a new volume with given size from the snapshot.
|
|
||||||
*
|
|
||||||
* This method blocks until the operations are fully completed.
|
|
||||||
*
|
|
||||||
* @param volume volume to be cloned
|
|
||||||
* @param newSize size of new volume
|
|
||||||
* @return newly created volume
|
|
||||||
*/
|
|
||||||
public Volume cloneVolumeWithNewSize(Volume volume, int newSize) {
|
|
||||||
Snapshot createdSnapshot =
|
|
||||||
elasticBlockStoreServices.createSnapshotInRegion(volume.getRegion(), volume.getId(),
|
|
||||||
CreateSnapshotOptions.Builder.withDescription("snapshot to test extending volumes"));
|
|
||||||
checkState(snapshotCompleted.apply(createdSnapshot),
|
|
||||||
/*or throw*/ "Couldn't create a snapshot");
|
|
||||||
|
|
||||||
Volume newVolume = elasticBlockStoreServices.createVolumeFromSnapshotInAvailabilityZone(
|
|
||||||
volume.getAvailabilityZone(), newSize,
|
|
||||||
createdSnapshot.getId());
|
|
||||||
checkState(volumeAvailable.apply(newVolume),
|
|
||||||
/*or throw*/ "Couldn't create a volume from the snapshot");
|
|
||||||
|
|
||||||
elasticBlockStoreServices.deleteSnapshotInRegion(volume.getRegion(), createdSnapshot.getId());
|
|
||||||
return newVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attaches volume to a (stopped) instance.
|
|
||||||
*
|
|
||||||
* This method blocks until the operations are fully completed.
|
|
||||||
* @param volume
|
|
||||||
* volume to attach
|
|
||||||
* @param instance
|
|
||||||
* instance to which the volume is to be attached, must be in
|
|
||||||
* a 'stopped' state
|
|
||||||
*/
|
|
||||||
public void attachVolumeToStoppedInstance(Volume volume, RunningInstance instance) {
|
|
||||||
Attachment volumeAttachment = elasticBlockStoreServices.
|
|
||||||
attachVolumeInRegion(instance.getRegion(), volume.getId(), instance.getId(),
|
|
||||||
instance.getRootDeviceName());
|
|
||||||
checkState(volumeAttached.apply(volumeAttachment),
|
|
||||||
/*or throw*/ "Couldn't attach volume back to the instance");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed 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.tools.ebsresize.facade;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import org.jclouds.aws.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.aws.ec2.predicates.InstanceStateStopped;
|
|
||||||
import org.jclouds.aws.ec2.services.InstanceClient;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Aggregates several methods of jClouds' EC2 functionality
|
|
||||||
* to work with instance client (instance store). These
|
|
||||||
* features are specific to instances with EBS root device.
|
|
||||||
*
|
|
||||||
* @author Oleksiy Yarmula
|
|
||||||
*/
|
|
||||||
public class InstanceFacade {
|
|
||||||
|
|
||||||
final private InstanceClient instanceServices;
|
|
||||||
final private Predicate<RunningInstance> instanceRunning;
|
|
||||||
final private Predicate<RunningInstance> instanceStopped;
|
|
||||||
|
|
||||||
public InstanceFacade(InstanceClient instanceServices) {
|
|
||||||
this.instanceServices = instanceServices;
|
|
||||||
this.instanceRunning =
|
|
||||||
new RetryablePredicate<RunningInstance>(new InstanceStateRunning(instanceServices),
|
|
||||||
600, 10, TimeUnit.SECONDS);
|
|
||||||
this.instanceStopped =
|
|
||||||
new RetryablePredicate<RunningInstance>(new InstanceStateStopped(instanceServices),
|
|
||||||
600, 10, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts an instance, given that it has an EBS volume attached.
|
|
||||||
* This command is only available for EC2 instances with
|
|
||||||
* EBS root device.
|
|
||||||
*
|
|
||||||
* This method blocks until the operations are fully completed.
|
|
||||||
*
|
|
||||||
* @param instance instance to start
|
|
||||||
* @see #stopInstance(org.jclouds.aws.ec2.domain.RunningInstance)
|
|
||||||
*/
|
|
||||||
public void startInstance(RunningInstance instance) {
|
|
||||||
instanceServices.startInstancesInRegion(instance.getRegion(), instance.getId());
|
|
||||||
checkState(instanceRunning.apply(instance),
|
|
||||||
/*or throw*/ "Couldn't start the instance");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops an instance.
|
|
||||||
* This command is only available for EC2 instances with
|
|
||||||
* EBS root device.
|
|
||||||
*
|
|
||||||
* This method blocks until the operations are fully completed.
|
|
||||||
*
|
|
||||||
* @param instance instance to stop
|
|
||||||
* @see #startInstance(org.jclouds.aws.ec2.domain.RunningInstance)
|
|
||||||
*/
|
|
||||||
public void stopInstance(RunningInstance instance) {
|
|
||||||
instanceServices.stopInstancesInRegion(instance.getRegion(), false, instance.getId());
|
|
||||||
checkState(instanceStopped.apply(instance),
|
|
||||||
/*or throw*/ "Couldn't stop the instance");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given an instance id and its {@link Region}, returns a {@link RunningInstance}.
|
|
||||||
*
|
|
||||||
* @param instanceId id of instance
|
|
||||||
* @param region region of the instance
|
|
||||||
* @return instance, corresponding to instanceId and region
|
|
||||||
*/
|
|
||||||
public RunningInstance getInstanceByIdAndRegion(String instanceId, Region region) {
|
|
||||||
Set<Reservation> reservations = instanceServices.describeInstancesInRegion(region, instanceId);
|
|
||||||
Reservation reservation = checkNotNull(Iterables.getOnlyElement(reservations));
|
|
||||||
return Iterables.getOnlyElement(reservation);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed 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.tools.ebsresize.util;
|
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.base.Predicates;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
|
||||||
import org.jclouds.compute.predicates.RunScriptRunning;
|
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.jclouds.ssh.SshClient;
|
|
||||||
import org.jclouds.ssh.jsch.JschSshClient;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allows remote command execution on instance.
|
|
||||||
*
|
|
||||||
* This is based on {@link org.jclouds.ssh.SshClient} and
|
|
||||||
* {@link org.jclouds.compute.util.ComputeUtils}, with
|
|
||||||
* some convenience methods.
|
|
||||||
*
|
|
||||||
* @see org.jclouds.ssh.SshClient
|
|
||||||
* @see org.jclouds.compute.util.ComputeUtils
|
|
||||||
*
|
|
||||||
* @author Oleksiy Yarmula
|
|
||||||
*/
|
|
||||||
public class SshExecutor {
|
|
||||||
|
|
||||||
private final Predicate<SshClient> runScriptRunning =
|
|
||||||
new RetryablePredicate<SshClient>(Predicates.not(new RunScriptRunning()),
|
|
||||||
600, 3, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
private final NodeMetadata nodeMetadata;
|
|
||||||
private final SshClient sshClient;
|
|
||||||
private final ComputeUtils utils;
|
|
||||||
|
|
||||||
public SshExecutor(NodeMetadata nodeMetadata,
|
|
||||||
Credentials instanceCredentials,
|
|
||||||
String keyPair,
|
|
||||||
InetSocketAddress socket) {
|
|
||||||
this.nodeMetadata = nodeMetadata;
|
|
||||||
|
|
||||||
this.sshClient =
|
|
||||||
new JschSshClient(socket, 60000,
|
|
||||||
instanceCredentials.account, keyPair.getBytes());
|
|
||||||
|
|
||||||
this.utils = new ComputeUtils(null, runScriptRunning, null);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void connect() {
|
|
||||||
sshClient.connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void execute(String command) {
|
|
||||||
|
|
||||||
ComputeUtils.RunScriptOnNode script = utils.runScriptOnNode(nodeMetadata,
|
|
||||||
"basicscript.sh", command.getBytes());
|
|
||||||
|
|
||||||
script.setConnection(sshClient, Logger.CONSOLE);
|
|
||||||
|
|
||||||
try {
|
|
||||||
script.call();
|
|
||||||
} catch(Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,207 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
|
||||||
*
|
|
||||||
* ====================================================================
|
|
||||||
* Licensed 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.tools.ebsresize;
|
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.google.common.io.Files;
|
|
||||||
import org.jclouds.aws.domain.Region;
|
|
||||||
import org.jclouds.aws.ec2.domain.*;
|
|
||||||
import org.jclouds.aws.ec2.domain.Volume;
|
|
||||||
import org.jclouds.aws.ec2.predicates.InstanceStateRunning;
|
|
||||||
import org.jclouds.aws.ec2.predicates.InstanceStateTerminated;
|
|
||||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
|
||||||
import org.jclouds.compute.ComputeService;
|
|
||||||
import org.jclouds.compute.domain.*;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
|
||||||
import org.testng.annotations.*;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.SortedSet;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests the resizing of instance's root EBS device.
|
|
||||||
*
|
|
||||||
* This test creates an instance, then resizes its root volume
|
|
||||||
* (which includes stopping it) and terminates it afterwards.
|
|
||||||
*
|
|
||||||
* @author Oleksiy Yarmula
|
|
||||||
*/
|
|
||||||
@Test(groups = {"live" }, enabled = true, testName = "ec2.demo.InstanceVolumeManagerLiveTest")
|
|
||||||
public class InstanceVolumeManagerLiveTest {
|
|
||||||
|
|
||||||
private final int NEW_SIZE = 6;
|
|
||||||
|
|
||||||
private String tag;
|
|
||||||
private String secret;
|
|
||||||
private InstanceVolumeManager manager;
|
|
||||||
private ComputeService client;
|
|
||||||
private Template template;
|
|
||||||
private Predicate<RunningInstance> instanceRunning;
|
|
||||||
private Predicate<RunningInstance> instanceTerminated;
|
|
||||||
private RunningInstance instanceCreated;
|
|
||||||
private Volume volumeAttached;
|
|
||||||
|
|
||||||
@BeforeTest
|
|
||||||
public void setupClient() throws IOException {
|
|
||||||
|
|
||||||
//set up the constants needed to run
|
|
||||||
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
|
||||||
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
|
||||||
|
|
||||||
String secretKeyFile = checkNotNull(System.getProperty("jclouds.test.ssh.keyfile"),
|
|
||||||
"jclouds.test.ssh.keyfile");
|
|
||||||
tag = "ec2";
|
|
||||||
|
|
||||||
//ended setting up the constants
|
|
||||||
|
|
||||||
secret = Files.toString(new File(secretKeyFile), Charsets.UTF_8);
|
|
||||||
assert secret.startsWith("-----BEGIN RSA PRIVATE KEY-----") : "invalid key:\n" + secret;
|
|
||||||
|
|
||||||
//create a new manager
|
|
||||||
Properties testOnlyProperties = new Properties();
|
|
||||||
testOnlyProperties.put(EC2Constants.PROPERTY_EC2_AMI_OWNERS, "819060954727");
|
|
||||||
manager = new InstanceVolumeManager(user, password, testOnlyProperties);
|
|
||||||
client = manager.getContext().getComputeService();
|
|
||||||
|
|
||||||
TemplateBuilder templateBuilder = client.templateBuilder();
|
|
||||||
template =
|
|
||||||
templateBuilder.imageId("ami-2675974f").
|
|
||||||
build();
|
|
||||||
template.getOptions().installPrivateKey(secret);
|
|
||||||
|
|
||||||
instanceRunning =
|
|
||||||
new RetryablePredicate<RunningInstance>(new InstanceStateRunning(manager.getApi().
|
|
||||||
getInstanceServices()),
|
|
||||||
600, 10, TimeUnit.SECONDS);
|
|
||||||
instanceTerminated =
|
|
||||||
new RetryablePredicate<RunningInstance>(new InstanceStateTerminated(manager.getApi().
|
|
||||||
getInstanceServices()),
|
|
||||||
600, 10, TimeUnit.SECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testResizeVolume() {
|
|
||||||
SortedSet<NodeMetadata> nodes = Sets.newTreeSet(
|
|
||||||
client.runNodesWithTag(tag, 1, template).values()
|
|
||||||
);
|
|
||||||
assert nodes.size() == 1 : "Expected to have 1 nodes created; found: " + nodes.size();
|
|
||||||
|
|
||||||
NodeMetadata launchedNode = Iterables.getOnlyElement(nodes);
|
|
||||||
|
|
||||||
AvailabilityZone availabilityZone = AvailabilityZone.fromValue(launchedNode.getLocationId());
|
|
||||||
Region region = getRegionNameForAvailabilityZone(availabilityZone);
|
|
||||||
|
|
||||||
instanceCreated = getOnlyInstance(launchedNode.getId(), region);
|
|
||||||
|
|
||||||
waitForInstanceInRunningState();
|
|
||||||
|
|
||||||
manager.resizeVolume(launchedNode.getId(), region, new Credentials("ubuntu", ""),
|
|
||||||
secret, NEW_SIZE);
|
|
||||||
|
|
||||||
// re-fetch the instance after the resize
|
|
||||||
// NOTE: this step is essential
|
|
||||||
instanceCreated = getOnlyInstance(launchedNode.getId(), region);
|
|
||||||
|
|
||||||
volumeAttached = manager.getEbsApi().getRootVolumeForInstance(instanceCreated);
|
|
||||||
checkState(volumeAttached.getSize() == NEW_SIZE,
|
|
||||||
String.format("The size of the new volume expected: " +
|
|
||||||
"%d. Found: %d", NEW_SIZE, volumeAttached.getSize()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterTest
|
|
||||||
public void close() {
|
|
||||||
manager.getApi().getInstanceServices().terminateInstancesInRegion
|
|
||||||
(instanceCreated.getRegion(), instanceCreated.getId());
|
|
||||||
checkState(instanceTerminated.apply(instanceCreated), "" +
|
|
||||||
/*or throw*/ "Couldn't terminate the instance");
|
|
||||||
if(volumeAttached != null) {
|
|
||||||
manager.getApi().getElasticBlockStoreServices().deleteVolumeInRegion
|
|
||||||
(volumeAttached.getRegion(), volumeAttached.getId());
|
|
||||||
}
|
|
||||||
manager.closeContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns region that has the given availability zone, or null,
|
|
||||||
* when nothing is found.
|
|
||||||
* This operates under the assumption that names of availability zones are
|
|
||||||
* unique, or else it returns the first matched region.
|
|
||||||
*
|
|
||||||
* @param zone
|
|
||||||
* zone that needs to be matched with region. This can not be null.
|
|
||||||
* @return region
|
|
||||||
* that has the provided zone
|
|
||||||
*/
|
|
||||||
private Region getRegionNameForAvailabilityZone(AvailabilityZone zone) {
|
|
||||||
for (Region region : ImmutableSet.of(Region.DEFAULT, Region.EU_WEST_1, Region.US_EAST_1,
|
|
||||||
Region.US_WEST_1)) {
|
|
||||||
SortedSet<AvailabilityZoneInfo> allResults = Sets.newTreeSet(manager.getApi().
|
|
||||||
getAvailabilityZoneAndRegionServices()
|
|
||||||
.describeAvailabilityZonesInRegion(region));
|
|
||||||
for(AvailabilityZoneInfo zoneInfo : allResults) {
|
|
||||||
if(zone == zoneInfo.getZone()) return zoneInfo.getRegion();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null; /*by contract*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Blocks until {@link #instanceCreated} transitions
|
|
||||||
* into 'running' state.
|
|
||||||
* NOTE: {@link #instanceCreated} can not be null.
|
|
||||||
*/
|
|
||||||
private void waitForInstanceInRunningState() {
|
|
||||||
checkState(instanceRunning.apply(instanceCreated),
|
|
||||||
/*or throw*/ "Couldn't run the instance");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link RunningInstance} object by instanceId and
|
|
||||||
* region.
|
|
||||||
*
|
|
||||||
* @param instanceId
|
|
||||||
* id of launched instance
|
|
||||||
* @param region
|
|
||||||
* region where the instance was launched
|
|
||||||
* @return corresponding {@link RunningInstance} object
|
|
||||||
*/
|
|
||||||
private RunningInstance getOnlyInstance(String instanceId, Region region) {
|
|
||||||
return Iterables.getOnlyElement(
|
|
||||||
Iterables.getOnlyElement(
|
|
||||||
manager.getApi().
|
|
||||||
getInstanceServices().
|
|
||||||
describeInstancesInRegion(region, instanceId
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue