package org.xmlsh.aws; import java.io.IOException; import java.util.List; import javax.xml.stream.XMLStreamException; import net.sf.saxon.s9api.SaxonApiException; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.xmlsh.aws.util.AWSEC2Command; import org.xmlsh.core.CoreException; import org.xmlsh.core.InvalidArgumentException; import org.xmlsh.core.Options; import org.xmlsh.core.UnexpectedException; import org.xmlsh.core.XValue; import org.xmlsh.util.Util; import com.amazonaws.AmazonServiceException; import com.amazonaws.services.ec2.model.CreateVolumeRequest; import com.amazonaws.services.ec2.model.CreateVolumeResult; import com.amazonaws.services.ec2.model.VolumeType; public class ec2CreateVolume extends AWSEC2Command { private static Logger mLogger = LogManager.getLogger(ec2CreateVolume.class); /** * @param args * @throws IOException */ @Override public int run(List<XValue> args) throws Exception { Options opts = getOptions("t=type:,s=size:,zone=availability-zone:,iops:,snapshot=snapshot-id:,spec=volspec:,+encrypted"); parseOptions(opts, args); args = opts.getRemainingArgs(); setSerializeOpts(this.getSerializeOpts(opts)); rateRetry = opts.getOptInt("rate-retry", 0); try { getEC2Client(opts); } catch (UnexpectedException e) { usage( e.getLocalizedMessage() ); return 1; } int ret = create( opts ); return ret; } private int create(Options opts ) throws IOException, XMLStreamException, SaxonApiException, InterruptedException, CoreException { CreateVolumeRequest request = new CreateVolumeRequest() .withAvailabilityZone(opts.getOptStringRequired("zone")) .withVolumeType(VolumeType.Gp2); // Default to GP2 /** * The volume type. This can be <code>gp2</code> for General Purpose * (SSD) volumes, <code>io1</code> for Provisioned IOPS (SSD) volumes, or * <code>standard</code> for Magnetic volumes. <p>Default: * <code>standard</code> * <p> * <b>Constraints:</b><br/> * <b>Allowed Values: </b>standard, io1, gp2 */ if(opts.hasOpt("spec")) parseVolumeSpec( opts.getOptStringRequired("spec") , request ); // Overrides if(opts.hasOpt("type")) request.setVolumeType(opts.getOptStringRequired("type")); if( opts.hasOpt("size")) request.setSize( opts.getOptInt("size", 10)); if( opts.hasOpt("snapshot")) request.setSnapshotId(opts.getOptStringRequired("snapshot")); if( opts.hasOpt("iops")) request.setIops(opts.getOptInt("iops", 100)); if( opts.hasOpt("encrypted")) request.setEncrypted(opts.getOptFlag("encrypted", false)); traceCall("createVolume"); CreateVolumeResult result = null ; int retry = rateRetry ; int delay = retryDelay ; do { try { result= mAmazon.createVolume(request); break ; } catch( AmazonServiceException e ){ mShell.printErr("AmazonServiceException" , e ); if( retry > 0 && Util.isEqual("RequestLimitExceeded",e.getErrorCode())){ mShell.printErr("AWS RequestLimitExceeded - sleeping " + delay ); Thread.sleep( delay ); retry--; delay *= 2 ; } else throw e; } } while( retry > 0 ); writeResult(result); return 0; } // [snapshot-id]:[volume-size]:[delete-on-termination]:[volume-type[:iops]]:[encrypted private void parseVolumeSpec(String spec, CreateVolumeRequest request) throws InvalidArgumentException { // Parse out the EBS stuff // [snapshot-id]:[volume-size]:[volume-type[:iops]]:[encrypted] String aebs[] = spec.split(":"); // [snapshot-id]: if( aebs.length >= 1 ){ String snapshotId = aebs[0]; if( ! Util.isBlank(snapshotId)) request.setSnapshotId(snapshotId); } // :[volume-size]: if( aebs.length >= 2 ){ if( !Util.isBlank(aebs[1])) request.setSize( new Integer( aebs[1])); } // [delete-on-termination] ignored for create-volume but keep placeholder if( aebs.length >= 3 ){ if( !Util.isBlank(aebs[2])) printErr("delete-on-termination flag ignored for dynamicly created volumes"); // ebs.setDeleteOnTermination( Boolean.valueOf( Util.parseBoolean(aebs[2]))); } if( aebs.length >= 4 ){ // [volume-type[:iops]]:[encrypted] int i = 3; if( !Util.isBlank(aebs[i])){ request.setVolumeType(aebs[i]); if( aebs[i].equals( VolumeType.Io1.toString())) { i++ ; if( aebs.length <= i || Util.isBlank(aebs[i]) ) throw new InvalidArgumentException("EBS block mapping with VolumeType io1 MUST have PIOPS"); request.setIops( Integer.valueOf( aebs[i])); } i++; if( aebs.length > i && ! Util.isBlank(aebs[i])) request.setEncrypted( Util.parseBoolean(aebs[i])); } } } private void writeResult(CreateVolumeResult result) throws IOException, XMLStreamException, SaxonApiException, CoreException { startResult(); writeVolume( result.getVolume() ); endResult(); } }