Repository: brooklyn-server Updated Branches: refs/heads/master 11b0ea703 -> 1f8f9eb9d
Adds EBS Location Customizers Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/6b828952 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/6b828952 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/6b828952 Branch: refs/heads/master Commit: 6b828952bfb50246f0db7f8fe6ec195a9648661b Parents: 5361c4d Author: Martin Harris <[email protected]> Authored: Wed May 10 15:00:23 2017 +0100 Committer: Martin Harris <[email protected]> Committed: Thu May 18 12:22:56 2017 +0100 ---------------------------------------------------------------------- .../aws/AbstractEbsVolumeCustomizer.java | 96 +++++++++++ .../jclouds/aws/EbsVolumeCustomizers.java | 170 +++++++++++++++++++ 2 files changed, 266 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b828952/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/AbstractEbsVolumeCustomizer.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/AbstractEbsVolumeCustomizer.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/AbstractEbsVolumeCustomizer.java new file mode 100644 index 0000000..741eb0e --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/AbstractEbsVolumeCustomizer.java @@ -0,0 +1,96 @@ +/* + * 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.apache.brooklyn.location.jclouds.aws; + +import org.apache.brooklyn.location.jclouds.BasicJcloudsLocationCustomizer; +import org.apache.brooklyn.location.jclouds.JcloudsLocation; +import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation; +import org.jclouds.aws.ec2.compute.AWSEC2ComputeService; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.domain.TemplateBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; + +public abstract class AbstractEbsVolumeCustomizer extends BasicJcloudsLocationCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractEbsVolumeCustomizer.class); + + protected String availabilityZone; + protected String ec2DeviceName; + protected String osDeviceName; + protected String mountPoint; + protected String owner; + protected Integer permissions; + + public void setAvailabilityZone(String availabilityZone) { + this.availabilityZone = availabilityZone; + } + + public void setEc2DeviceName(String ec2DeviceName) { + this.ec2DeviceName = ec2DeviceName; + } + + public void setOsDeviceName(String osDeviceName) { + this.osDeviceName = osDeviceName; + } + + public void setMountPoint(String mountPoint) { + this.mountPoint = mountPoint; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public void setPermissions(Integer permissions) { + this.permissions = permissions; + } + + @Override + public void customize(JcloudsLocation location, ComputeService computeService, TemplateBuilder templateBuilder) { + if (computeService instanceof AWSEC2ComputeService) { + templateBuilder.locationId(availabilityZone); + } else { + LOG.debug("Skipping configuration of non-EC2 ComputeService {}", computeService); + } + } + + protected void createFilesystem(JcloudsSshMachineLocation machine, String filesystemType) { + machine.execCommands("Creating filesystem on EBS volume", ImmutableList.of( + "sudo mkfs." + filesystemType + " " + osDeviceName + )); + } + + protected void mountFilesystem(JcloudsSshMachineLocation machine) { + // NOTE: also adds an entry to fstab so the mount remains available after a reboot. + Builder<String> commands = ImmutableList.<String>builder().add( + "sudo mkdir -m 000 " + mountPoint, + "sudo echo \"" + osDeviceName + " " + mountPoint + " auto noatime 0 0\" | sudo tee -a /etc/fstab", + "sudo mount " + mountPoint, + "sudo chown " + (owner == null ? machine.getUser() : owner) + " " + mountPoint + ); + if (permissions != null) { + commands.add("sudo chmod " + permissions + " " + mountPoint); + } + machine.execCommands("Mounting EBS volume", commands.build()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6b828952/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/EbsVolumeCustomizers.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/EbsVolumeCustomizers.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/EbsVolumeCustomizers.java new file mode 100644 index 0000000..4777aed --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/aws/EbsVolumeCustomizers.java @@ -0,0 +1,170 @@ +/* + * 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.apache.brooklyn.location.jclouds.aws; + +import org.apache.brooklyn.location.jclouds.JcloudsLocation; +import org.apache.brooklyn.location.jclouds.JcloudsMachineLocation; +import org.apache.brooklyn.location.jclouds.JcloudsSshMachineLocation; +import org.jclouds.aws.ec2.AWSEC2Api; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.EC2ComputeService; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.features.ElasticBlockStoreApi; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customization hooks to ensure that any EC2 instances provisioned via a corresponding jclouds location become associated + * with an EBS volume (either an existing volume, specified by ID, or newly created). + */ +public class EbsVolumeCustomizers { + + private static final Logger LOG = LoggerFactory.getLogger(EbsVolumeCustomizers.class); + + /** + * Location customizer that: + * <ul> + * <li>configures the AWS availability zone</li> + * <li>creates a new EBS volume of the requested size in the given availability zone</li> + * <li>attaches the new volume to the newly-provisioned EC2 instance</li> + * <li>formats the new volume with the requested filesystem</li> + * <li>mounts the filesystem under the requested path</li> + * </ul> + */ + public static class WithNewVolume extends AbstractEbsVolumeCustomizer { + private String filesystemType; + private int sizeInGib; + private boolean deleteOnTermination; + + public void setFilesystemType(String filesystemType) { + this.filesystemType = filesystemType; + } + + public void setSizeInGib(int sizeInGib) { + this.sizeInGib = sizeInGib; + } + + public void setDeleteOnTermination(boolean deleteOnTermination) { + this.deleteOnTermination = deleteOnTermination; + } + + @Override + public void customize(JcloudsLocation location, ComputeService computeService, TemplateOptions templateOptions) { + if (templateOptions instanceof EC2TemplateOptions) { + ((EC2TemplateOptions) templateOptions).mapNewVolumeToDeviceName(ec2DeviceName, sizeInGib, deleteOnTermination); + } else { + LOG.debug("Skipping configuration of non-EC2 TemplateOptions {}", templateOptions); + } + } + + @Override + public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) { + if (computeService instanceof EC2ComputeService) { + createFilesystem((JcloudsSshMachineLocation) machine, filesystemType); + mountFilesystem((JcloudsSshMachineLocation) machine); + } else { + LOG.debug("Skipping configuration of non-EC2 ComputeService {}", computeService); + } + } + } + + /** + * Location customizer that: + * <ul> + * <li>configures the AWS availability zone</li> + * <li>obtains a new EBS volume from the specified snapshot in the given availability zone</li> + * <li>attaches the new volume to the newly-provisioned EC2 instance</li> + * <li>mounts the filesystem under the requested path</li> + * </ul> + */ + public static class WithExistingSnapshot extends AbstractEbsVolumeCustomizer { + private String snapshotId; + private int sizeInGib; + private boolean deleteOnTermination; + + public void setSnapshotId(String snapshotId) { + this.snapshotId = snapshotId; + } + + public void setSizeInGib(int sizeInGib) { + this.sizeInGib = sizeInGib; + } + + public void setDeleteOnTermination(boolean deleteOnTermination) { + this.deleteOnTermination = deleteOnTermination; + } + + @Override + public void customize(JcloudsLocation location, ComputeService computeService, TemplateOptions templateOptions) { + if (templateOptions instanceof EC2TemplateOptions) { + ((EC2TemplateOptions) templateOptions).mapEBSSnapshotToDeviceName(ec2DeviceName, snapshotId, sizeInGib, deleteOnTermination); + } else { + LOG.debug("Skipping configuration of non-EC2 TemplateOptions {}", templateOptions); + } + } + + @Override + public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) { + if (computeService instanceof EC2ComputeService) { + mountFilesystem((JcloudsSshMachineLocation) machine); + } else { + LOG.debug("Skipping configuration of non-EC2 ComputeService {}", computeService); + } + } + } + + /** + * Location customizer that: + * <ul> + * <li>configures the AWS availability zone</li> + * <li>attaches the specified (existing) volume to the newly-provisioned EC2 instance</li> + * <li>mounts the filesystem under the requested path</li> + * </ul> + */ + public static class WithExistingVolume extends AbstractEbsVolumeCustomizer { + private String region; + private String volumeId; + + public void setRegion(String region) { + this.region = region; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + @Override + public void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine) { + if (computeService instanceof EC2ComputeService) { + AWSEC2Api ec2Client = computeService.getContext().unwrapApi(AWSEC2Api.class); + ElasticBlockStoreApi ebsClient = ec2Client.getElasticBlockStoreApi().get(); + ebsClient.attachVolumeInRegion(region, volumeId, machine.getJcloudsId(), ec2DeviceName); + mountFilesystem((JcloudsSshMachineLocation) machine); + } else { + LOG.debug("Skipping configuration of non-EC2 ComputeService {}", computeService); + } + } + } + + // Prevent construction: helper class. + private EbsVolumeCustomizers() { + } + +} \ No newline at end of file
