.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "VM::EC2::Staging::Volume 3pm" .TH VM::EC2::Staging::Volume 3pm "2016-06-04" "perl v5.22.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" VM::EC2::Staging::Volume \- High level functions for provisioning and populating EC2 volumes .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use VM::EC2::Staging::manager; \& \& # get a new staging manager \& my $ec2 = VM::EC2\->new; \& my $staging = $ec2\->staging_manager(); ); \& \& my $vol1 = $staging\->get_volume(\-name => \*(AqBackup\*(Aq, \& \-fstype => \*(Aqext4\*(Aq, \& \-size => 11, \& \-zone => \*(Aqus\-east\-1a\*(Aq); \& \& # make a couple of directories in new volume \& $vol1\->mkdir(\*(Aqpictures\*(Aq); \& $vol1\->mkdir(\*(Aqvideos\*(Aq); \& \& # use rsync to copy local files onto a subdirectory of this volume \& $vol1\->put(\*(Aq/usr/local/my_pictures/\*(Aq =>\*(Aqpictures\*(Aq); \& $vol1\->put(\*(Aq/usr/local/my_videos/\*(Aq =>\*(Aqvideos\*(Aq); \& \& # use rsync to to copy a set of files on the volume to a local directory \& mkdir(\*(Aq/tmp/jpegs\*(Aq); \& $vol1\->get(\*(Aqpictures/*.jpg\*(Aq,\*(Aq/tmp/jpegs\*(Aq); \& \& # note that these commands are executed on the remote server as root! \& @listing = $vol1\->ls(\*(Aq\-r\*(Aq,\*(Aqpictures\*(Aq); \& $vol1\->chown(\*(Aqfred\*(Aq,\*(Aqpictures\*(Aq); \& $vol1\->chgrp(\*(Aqnobody\*(Aq,\*(Aqpictures\*(Aq); \& $vol1\->chmod(\*(Aq0700\*(Aq,\*(Aqpictures\*(Aq); \& $vol1\->rm(\*(Aq\-rf\*(Aq,\*(Aqpictures/*\*(Aq); \& $vol1\->rmdir(\*(Aqpictures\*(Aq); \& \& # get some information about the volume \& my $mtpt = $vol\->mtpt; \& my $mtdev = $vol\->mtdev; \& my $mounted = $vol\->mounted; \& my $server = $vol\->server; \& \& # detach the volume \& $vol\->detach; \& \& # delete the volume entirely \& $vol\->delete; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This is a high-level interface to \s-1EBS\s0 volumes which is used in conjunction with VM::EC2::Staging::Manager and VM::EC2::Staging::Server. It is intended to ease the process of allocating and managing \s-1EBS\s0 volumes, and provides for completely automated filesystem creation, directory management, and data transfer to and from the volume. .PP You can use staging volumes without having to manually create and manage the instances needed to manipulate the volumes. As needed, the staging manager will create the server(s) needed to execute the desired actions on the volumes. .PP Staging volumes are wrappers around VM::EC2::Volume, and have all the methods associated with those objects. In addition to the standard \s-1EC2\s0 volume characteristics, each staging volume in an \s-1EC2\s0 region has a symbolic name, which can be used to retrieve previously-created volumes without remembering their volume \s-1ID.\s0 This symbolic name is stored in the tag StagingName. Volumes also have a filesystem type (stored in the tag StagingFsType). When a volume is mounted on a staging server, it will also have a mount point on the file system, and a mounting device (e.g. /dev/sdf1). .SH "Staging Volume Creation" .IX Header "Staging Volume Creation" Staging volumes are created via a staging manager's \fIget_volume()\fR or \&\fIprovision_volume()\fR methods. See VM::EC2::Staging::Manager. One typical invocation is: .PP .Vb 6 \& my $ec2 = VM::EC2\->new; \& my $manager = $ec2\->staging_manager(); ); \& my $vol = $manager\->get_volume(\-name => \*(AqBackup\*(Aq, \& \-fstype => \*(Aqext4\*(Aq, \& \-size => 5, \& \-zone => \*(Aqus\-east\-1a\*(Aq); .Ve .PP This will either retrieve an existing volume named \*(L"Backup\*(R", or, if none exists, create a new one using the provided specification. Behind the scenes, a staging server will be allocated to mount the volume. The manager tries to conserve resources, and so will reuse a suitable running staging server if one is available. .PP The other typical invocation is: .PP .Vb 4 \& my $vol = $manager\->provision_volume(\-name => \*(AqBackup\*(Aq, \& \-fstype => \*(Aqext4\*(Aq, \& \-size => 5, \& \-zone => \*(Aqus\-east\-1a\*(Aq); .Ve .PP This forces creation of a new volume with the indicated characteristics. If a volume of the same name already exists, this method will die with a fatal error (to avoid this, either wrap in an eval, or leave off the \-name argument and let the manager pick a unique name for you). .SH "Volume Information" .IX Header "Volume Information" The methods in this section return status information about the staging volume. .ie n .SS "$name = $vol\->name([$newname])" .el .SS "\f(CW$name\fP = \f(CW$vol\fP\->name([$newname])" .IX Subsection "$name = $vol->name([$newname])" Get/set the symbolic name associated with this volume. .ie n .SS "$mounted = $vol\->mounted" .el .SS "\f(CW$mounted\fP = \f(CW$vol\fP\->mounted" .IX Subsection "$mounted = $vol->mounted" Returns true if the volume is currently mounted on a server. .ie n .SS "$type = $vol\->fstype" .el .SS "\f(CW$type\fP = \f(CW$vol\fP\->fstype" .IX Subsection "$type = $vol->fstype" Return the filesystem type requested at volume creation time. .ie n .SS "$server = $vol\->server" .el .SS "\f(CW$server\fP = \f(CW$vol\fP\->server" .IX Subsection "$server = $vol->server" Get the server associated with this volume, if any. .ie n .SS "$device = $vol\->mtdev" .el .SS "\f(CW$device\fP = \f(CW$vol\fP\->mtdev" .IX Subsection "$device = $vol->mtdev" Get the device that the volume is attached to, e.g. /dev/sdf1. If the volume is not attached to a server, returns undef. .ie n .SS "$device = $vol\->mtpt" .el .SS "\f(CW$device\fP = \f(CW$vol\fP\->mtpt" .IX Subsection "$device = $vol->mtpt" Get the mount point for this volume on the attached server. If the volume is not mounted, returns undef. .ie n .SS "$ebs_vol = $vol\->ebs" .el .SS "\f(CW$ebs_vol\fP = \f(CW$vol\fP\->ebs" .IX Subsection "$ebs_vol = $vol->ebs" Get the underlying \s-1EBS\s0 volume associated with the staging volume object. .ie n .SS "$manager = $vol\->manager" .el .SS "\f(CW$manager\fP = \f(CW$vol\fP\->manager" .IX Subsection "$manager = $vol->manager" Return the VM::EC2::Staging::Manager which manages this volume. .ie n .SS "$string = $vol\->\fIfstab_line()\fP;" .el .SS "\f(CW$string\fP = \f(CW$vol\fP\->\fIfstab_line()\fP;" .IX Subsection "$string = $vol->fstab_line();" This method returns the line in /etc/fstab that would be necessary to mount this volume on the server to which it is currently attached at boot time. For example: .PP .Vb 1 \& /dev/sdf1 /mnt/staging/Backups ext4 defaults,nobootwait 0 2 .Ve .PP You can add this to the current server's fstab using the following code fragment: .PP .Vb 4 \& my $server = $vol\->server; \& my $fh = $server\->scmd_write(\*(Aqsudo \-s "cat >>/etc/fstab"\*(Aq); \& print $fh $vol\->fstab,"\en"; \& close $fh; .Ve .ie n .SS "$type = $vol\->get_fstype" .el .SS "\f(CW$type\fP = \f(CW$vol\fP\->get_fstype" .IX Subsection "$type = $vol->get_fstype" Return the volume's actual filesystem type. This can be different from the requested type if it was later altered by running mkfs on the volume, or the contents of the disk were overwritten by a block-level dd command. As a side effect, this method sets \fIfstype()\fR to the current correct value. .SH "Lifecycle Methods" .IX Header "Lifecycle Methods" The methods in this section control the state of the volume. .ie n .SS "$snapshot = $vol\->create_snapshot('description')" .el .SS "\f(CW$snapshot\fP = \f(CW$vol\fP\->create_snapshot('description')" .IX Subsection "$snapshot = $vol->create_snapshot('description')" Create a VM::EC2::Snapshot of the volume with an optional description. This differs from the VM::EC2::Volume method of the same name in that it is aware of the mount state of the volume and will first try to unmount it so that the snapshot is clean. After the snapshot is started, the volume is remounted. .ie n .SS "$snapshot = $vol\->snapshot('description')" .el .SS "\f(CW$snapshot\fP = \f(CW$vol\fP\->snapshot('description')" .IX Subsection "$snapshot = $vol->snapshot('description')" Identical to \fIcreate_snapshot()\fR, but the method name is shorter. .ie n .SS "$vol\->mount($server [,$mtpt])" .el .SS "\f(CW$vol\fP\->mount($server [,$mtpt])" .IX Subsection "$vol->mount($server [,$mtpt])" .ie n .SS "$vol\->\fImount()\fP" .el .SS "\f(CW$vol\fP\->\fImount()\fP" .IX Subsection "$vol->mount()" Mount the volume on the indicated VM::EC2::Staging::Server, optionally at a named mount point on the file system. If the volume is already attached to a different server, it will be detached first. If any of these step fails, the method will die with a fatal error. .PP When called with no arguments, the volume is automounted on a staging server, creating or starting the server if necessary. .ie n .SS "$vol\->\fIunmount()\fP" .el .SS "\f(CW$vol\fP\->\fIunmount()\fP" .IX Subsection "$vol->unmount()" Unmount the volume from wherever it is, but leave it attached to the staging server. If the volume is not already mounted, nothing happens. .PP Note that it is possible for a volume to be mounted on a \fIstopped\fR server, in which case the server will be started and the volume only unmounted when it is up and running. .ie n .SS "$vol\->\fIdetach()\fP" .el .SS "\f(CW$vol\fP\->\fIdetach()\fP" .IX Subsection "$vol->detach()" Unmount and detach the volume from its current server, if any. .PP Note that it is possible for a volume to be mounted on a \fIstopped\fR server, in which case the server will be started and the volume only unmounted when it is up and running. .ie n .SS "$vol\->\fIdelete()\fP" .el .SS "\f(CW$vol\fP\->\fIdelete()\fP" .IX Subsection "$vol->delete()" Delete the volume entirely. If it is mounted and/or attached to a server, it will be unmounted/detached first. If any steps fail, the method will die with a fatal error. .SH "Data Operations" .IX Header "Data Operations" The methods in this section operate on the contents of the volume. By and large, they operate with root privileges on the server machine via judicious use of sudo. Elevated permissions on the local machine (on which the script is running) are not needed. .ie n .SS "$vol\->get($source_on_vol_1,$source_on_vol_2,...,$dest)" .el .SS "\f(CW$vol\fP\->get($source_on_vol_1,$source_on_vol_2,...,$dest)" .IX Subsection "$vol->get($source_on_vol_1,$source_on_vol_2,...,$dest)" Invoke \fIrsync()\fR on the server to copy files & directories from the indicated source locations on the staging volume to the destination. Source paths can be relative paths, such as \&\*(L"media/photos/vacation\*(R", in which case they are relative to the top level of the mounted volume, or absolute paths, such as \&\*(L"/usr/local/media/photos/vacation\*(R", in which case they are treated as absolute paths on the server on which the volume is mounted. .PP The destination can be a path on the local machine, a host:/path on a remote machine, a staging server and path in the form \f(CW$server:\fR/path, or a staging volume and path in the form \*(L"$volume/path\*(R". See \&\*(L"Instance Methods for Managing Staging Volumes\*(R" in VM::EC2::Staging::Manager for more formats you can use. .PP As a special case, if you invoke \fIget()\fR with a single argument: .PP .Vb 1 \& $vol\->get(\*(Aq/tmp/foo\*(Aq) .Ve .PP Then the entire volume will be rsynced into the destination directory /tmp/foo. .ie n .SS "$vol\->copy($source_on_vol_1,$source_on_vol_2,...,$dest)" .el .SS "\f(CW$vol\fP\->copy($source_on_vol_1,$source_on_vol_2,...,$dest)" .IX Subsection "$vol->copy($source_on_vol_1,$source_on_vol_2,...,$dest)" This is an alias for \fIget()\fR. It is intended to make it easier to read the intent of this command: .PP .Vb 1 \& $source_volume\->copy($destination_volume); .Ve .PP Which basically makes a copy of \f(CW$source_volume\fR onto \&\f(CW$destination_volume\fR. .ie n .SS "$vol\->put($source1,$source2,$source3,...,$dest_on_volume)" .el .SS "\f(CW$vol\fP\->put($source1,$source2,$source3,...,$dest_on_volume)" .IX Subsection "$vol->put($source1,$source2,$source3,...,$dest_on_volume)" Invoke \fIrsync()\fR on the server to copy files & directories from the indicated source locations a destination located on the staging volume. The rules for paths are the same as for the \fIget()\fR method and as described in \&\*(L"Instance Methods for Managing Staging Volumes\*(R" in VM::EC2::Staging::Manager . .PP As a special case, if you invoke \fIput()\fR with a single argument: .PP .Vb 1 \& $vol\->put(\*(Aq/tmp/foo\*(Aq) .Ve .PP Then the local directory /tmp/foo will be copied onto the top level of the staging volume. To do something similar with multiple source directories, use '/' or '.' as the destination: .PP .Vb 1 \& $vol\->put(\*(Aq/tmp/pictures\*(Aq,\*(Aq/tmp/audio\*(Aq => \*(Aq/\*(Aq); .Ve .ie n .SS "$vol\->dd($destination_volume)" .el .SS "\f(CW$vol\fP\->dd($destination_volume)" .IX Subsection "$vol->dd($destination_volume)" The \fIdd()\fR method performs a block level copy of the volume's disk onto the destination. The destination must be another staging volume. .ie n .SS "$output = $vol\->cmd($cmd,@args)" .el .SS "\f(CW$output\fP = \f(CW$vol\fP\->cmd($cmd,@args)" .IX Subsection "$output = $vol->cmd($cmd,@args)" This method runs command \f(CW$cmd\fR on the server that is mounting the volume using ssh. Before the command is run, the working directory is changed to the top level of the volume's mount point. Any arguments, switches, etc you wish to pass to the command can be provided as \&\f(CW@args\fR. The output of the command is returned as a string in a scalar context, or an array of lines in a list context. .PP Example: .PP .Vb 1 \& @log = $volume\->cmd(\*(Aqtar cvf /tmp/archive.tar .\*(Aq); .Ve .ie n .SS "$result = $vol\->ssh($cmd,@args)" .el .SS "\f(CW$result\fP = \f(CW$vol\fP\->ssh($cmd,@args)" .IX Subsection "$result = $vol->ssh($cmd,@args)" This is similar to \fIcmd()\fR, except that the output of the command is sent to \s-1STDOUT\s0 and the method returns true if the command executed succcessfully on the remote machine. The \fIcmd()\fR and \fIssh()\fR methods are equivalent to backticks are \fIsystem()\fR respectively. .PP Example: .PP .Vb 1 \& $volume\->ssh(\*(Aqgzip /tmp/archive.tar\*(Aq) or die "couldn\*(Aqt compress archive"; .Ve .ie n .SS "$output = $vol\->df(@args)" .el .SS "\f(CW$output\fP = \f(CW$vol\fP\->df(@args)" .IX Subsection "$output = $vol->df(@args)" .ie n .SS "$output = $vol\->ls(@args)" .el .SS "\f(CW$output\fP = \f(CW$vol\fP\->ls(@args)" .IX Subsection "$output = $vol->ls(@args)" .ie n .SS "$success = $vol\->mkdir(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->mkdir(@args)" .IX Subsection "$success = $vol->mkdir(@args)" .ie n .SS "$success = $vol\->chown(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->chown(@args)" .IX Subsection "$success = $vol->chown(@args)" .ie n .SS "$success = $vol\->chgrp(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->chgrp(@args)" .IX Subsection "$success = $vol->chgrp(@args)" .ie n .SS "$success = $vol\->chmod(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->chmod(@args)" .IX Subsection "$success = $vol->chmod(@args)" .ie n .SS "$success = $vol\->cp(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->cp(@args)" .IX Subsection "$success = $vol->cp(@args)" .ie n .SS "$success = $vol\->mv(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->mv(@args)" .IX Subsection "$success = $vol->mv(@args)" .ie n .SS "$success = $vol\->rm(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->rm(@args)" .IX Subsection "$success = $vol->rm(@args)" .ie n .SS "$success = $vol\->rmdir(@args)" .el .SS "\f(CW$success\fP = \f(CW$vol\fP\->rmdir(@args)" .IX Subsection "$success = $vol->rmdir(@args)" Each of these methods performs the same function as the like-named command-line function, after first changing the working directory to the top level of the volume. They behave as shown in the pseudocode below: .PP .Vb 2 \& chdir $vol\->mtpt; \& sudo $method @args .Ve .PP The \fIdf()\fR and \fIls()\fR methods return the output of their corresponding commands. In a scalar context each method returns a string corresponding to the output of running the command on the server to which the volume is attached. In a list context, the methods return one element per line of output. .PP For example: .PP .Vb 3 \& my $free = $volume\->df(\*(Aq.\*(Aq); # free on current directory \& my ($percent) = $free =~ /(\ed+)%/; \& warn "almost out of space" if $percent > 90; .Ve .PP The other methods return a boolean value indicating successful execution of the command on the remote machine. .PP Command line switches can be passed along with other arguments: .PP .Vb 2 \& $volume\->mkdir(\*(Aq\-p\*(Aq,\*(Aqmedia/photos/vacation\*(Aq); \& $volume\->chown(\*(Aq\-R\*(Aq,\*(Aqfred\*(Aq,\*(Aqmedia\*(Aq); .Ve .PP With the exception of df, each of these commands runs as the superuser, so be careful how you call them. .PP You may run your own commands using the \fIcmd()\fR and \fIssh()\fR methods. The former returns the output of the command. The latter returns a success code: .PP .Vb 2 \& @log = $volume\->cmd(\*(Aqtar cvf /tmp/archive.tar .\*(Aq); \& $volume\->ssh(\*(Aqgzip /tmp/archive.tar\*(Aq) or die "couldn\*(Aqt compress archive"; .Ve .PP Before calling any of these methods, the volume must be mounted and its server running. A fatal error will occur otherwise. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\s-1VM::EC2\s0 VM::EC2::Staging::Manager VM::EC2::Staging::Server VM::EC2::Instance VM::EC2::Volume VM::EC2::Snapshot .SH "AUTHOR" .IX Header "AUTHOR" Lincoln Stein . .PP Copyright (c) 2012 Ontario Institute for Cancer Research .PP This package and its accompanying libraries is free software; you can redistribute it and/or modify it under the terms of the \s-1GPL \s0(either version 1, or at your option, any later version) or the Artistic License 2.0. Refer to \s-1LICENSE\s0 for the full license text. In addition, please see \s-1DISCLAIMER\s0.txt for disclaimers of warranty.