VM::EC...Server(3pm)
๐ฆ VM::EC2::Staging::Server(3pm) ๐ฆ
okay bestie, welcome to the <pink>User Contributed Perl Documentation</pink> page for VM::EC2::Staging::Server, section 3pm. it's giving very powerful, very ssh-heavy, and it's about to be your new favorite thing ๐
๐ธ NAME ๐ธ
VM::EC2::Staging::Server โ high level interface to EC2-based servers ๐ซถ
โจ SYNOPSIS โจ
okay so here's the whole vibe in one go, no cap:
use VM::EC2::Staging::Manager;
# get a new staging manager
my $ec2 = VM::EC2->new;
my $staging = $ec2->staging_manager(); );
# Fetch a server named 'my_server'. Create it if it does not already exist.
my $server1 = $staging->get_server(-name => 'my_server',
-availability_zone => 'us-east-1a',
-architecture => 'i386',
-instance_type => 't1.micro');
# As above, but force a new server to be provisioned.
my $server2 = $staging->provision_server(-name => 'my_server',
-availability_zone => 'us-east-1a',
-architecture => 'i386',
-instance_type => 't1.micro');
# open up a terminal emulator in a separate window
$server1->shell;
# Run a command over ssh on the server. Standard in and out will be connected to
# STDIN/OUT
$server1->ssh('whoami');
# run a command over ssh on the server, returning standard output as an array of lines or a
# scalar string, similar to backticks (``)
my @password_lines = $server1->scmd('cat /etc/passwd');
# run a command on the server and read from it using a filehandle
my $fh = $server1->scmd_read('ls -R /usr/lib');
while (<$fh>) { # do something }
# run a command on the server and write to it using a filehandle
my $fh = $server1->scmd_write('sudo -s "cat >>/etc/fstab"');
print $fh "/dev/sdf3 /mnt/demo ext3 0 2\n";
close $fh;
# provision and mount a 5 gig ext3 volume mounted on /opt, returning
# VM::EC2::Staging::Volume object
my $opt = $server1->provision_volume(-mtpt => '/opt',
-fstype => 'ext3',
-size => 5);
# copy some data from the local filesystem onto the opt volume
$server1->rsync("$ENV{HOME}/local_staging_volume/" => $opt);
# same thing, but using server path name
$server1->put("$ENV{HOME}/local_staging_volume/" => '/opt');
# provision a volume attached to another server, and let the
# system choose the filesystem and mount point for us
my $backups = $server2->provision_volume(-name => 'Backup',
-size => 10);
# copy some data from opt to the new volume using rsync
$server1->rsync($opt => "$backups/opt");
# Do a block-level copy between disks - warning, the filesystem must be unmounted
# before you attempt this.
$backups->unmount;
$server1->dd($opt => $backups);
๐ DESCRIPTION ๐
so VM::EC2::Staging::Server objects are literally an extension of VM::EC2::Instance that lets you do higher-level stuff, like easy management of ssh keys, remote copying of data from one server to another, and executing remote commands on the server from inside Perl. it's the glow-up arc, fr fr. if you want the big-picture overview of staging servers and volumes, go read VM::EC2::Staging::Manager ๐
heads up bestie ๐ this module's proper functioning is heavily dependent on running on a host system that actually has access tossh,rsyncand terminal emulator command-line tools. it will most likely fail when run on a Windows host. no Windows moment for you, sorry ๐
๐ Staging Server Creation ๐
staging servers are usually created through a staging manager's get_server() or provision_server() methods. peek at VM::EC2::Staging::Manager for that whole situation โจ
there's also a new() class method that's intended to be used internally in most cases. it gets called like this:
$server = VM::EC2::Staging::Server->new(%args)
with the arguments, and yes every single one of them matters ๐
-keyfileโ path to the ssh public/private keyfile for this instance-usernameโ username for remote login on this instance-instanceโVM::EC2::Instanceto attach this server to-managerโVM::EC2::Staging::Managerin same zone as the instance
real talk: you'll have to launch a staging manager, start an instance, and appropriate provision the SSH credentials for that instance before invoking new() directly. don't skip steps, babe ๐ซถ
๐ฆ Information about the Server ๐ฆ
VM::EC2::Staging::Server objects have all the methods of VM::EC2::Instance, like dnsName(), but they add several new ones too. the new methods that are all about getting basic info on the server live right here ๐
$name = $server->name
this one hands you the server's symbolic name, if it even has one ๐ธ
servers can optionally be assigned a symbolic name at the time they're created, via the manager's get_server() or provision_server() methods. the name persists as long as the underlying instance exists (including in stopped state for EBS-backed instances). and calling $manager->get_server() with this name returns the server object. iykyk ๐ซ
$ec2 = $server->ec2
returns the VM::EC2 object that's associated with the server.
$ec2 = $server->endpoint
returns the endpoint URL associated with this server.
$instance = $server->instance
returns the VM::EC2::Instance associated with this server.
$file = $server->keyfile
returns the full path to the SSH PEM keyfile used to log into this server.
$user = $server->username
returns the name of the user (e.g. 'ubuntu') used to ssh into this server.
$manager = $server->manager
returns the VM::EC2::Staging::Manager that manages this server.
๐ฅ Lifecycle Methods ๐ฅ
these ones run the whole start / stop / terminate arc of a server's life. main character energy only โจ
$flag = $server->ping
ping() returns true if the server is running and reachable via ssh. it's not the same as just checking that the underlying instance is "running" via a call to current_status, because it also checks the usability of the ssh daemon, the provided ssh key and username, firewall rules, and the network connectivity. full vibe check, basically ๐ง
the result of ping is cached so that subsequent invocations return quickly. slay.
$result = $server->start
attempts to start a stopped server. the method will wait until a ping() is successful, or until a timeout of 120 seconds. the result code will be true if the server was successfully started and is reachable. periodt.
if you want to start a set of servers without waiting on each one individually, then you may call the underling instance's start() method:
$server->instance->start;
you may then wish to call the staging manager's wait_for_instances() method to wait on all of the servers to start:
$manager->wait_for_servers(@servers);
also check out $manager->start_all_servers(). ๐
$result = $server->stop
attempts to stop a running server. the method will wait until the server has entered the "stopped" state before returning. it'll return a true result if the underlying instance stopped successfully.
if you want to stop a set of servers without waiting on each one individually, then you may call the underling instance's start() method:
$server->instance->stop;
you may then wish to call the staging manager's wait_for_instances() method to wait on all of the servers to start:
$status = $manager->wait_for_servers(@servers);
also check out $manager->stop_all_servers(). ๐
$result = $server->terminate
terminate a server and unregister it from the manager. this method will stop and wait until the server is terminated. bye bestie ๐๐ญ
if you want to stop a set of servers without waiting on each one individually, then you may call the underling instance's start() method:
$server->instance->terminate;
๐ Remote Shell Methods ๐
the methods in this section let you run remote commands on the staging server and interrogate the results. and since the staging manager handles the creation of SSH keys internally, you do not need to worry about finding the right public/private keypair. one less thing, bestie ๐ซถ
$result = $server->ssh(@command)
ssh() invokes a command on the remote server. you can hand it the command line as a single string, or break it up by argument:
$server->ssh('ls -lR /var/log');
$server->ssh('ls','-lR','/var/log');
the output of the command will appear on STDOUT and STDERR of the perl process. input, if needed, will be read from STDIN. and if you provide no command at all, then an interactive ssh session will be started on the remote server and the script will wait until you have logged out. iconic behavior.
if the remote command was successful, the method result will be true. โ
$output = $server->scmd(@command)
this is similar to ssh(), except the standard output of the remote command gets captured and returned as the function result โ kinda like how backticks work in perl:
my $output = $server->scmd('date');
print "The localtime for the server is $output";
$fh = $server->scmd_write(@command)
this method executes @command on the remote server, and returns a filehandle attached to the standard input of the command. here's a slightly dangerous example that appends a line to /etc/passwd:
my $fh = $server->scmd_write('sudo -s "cat >>/etc/passwd"');
print $fh "whoopsie:x:119:130::/nonexistent:/bin/false\n";
close $fh;
okay so that example is genuinely a little unhinged, the docs literally call it "slightly dangerous" ๐ don't be that girl.
$fh = $server->scmd_read(@command)
this method executes @command on the remote server, and returns a filehandle attached to the standard output of the command. here's an example of reading syslog:
my $fh = $server->scmd_read('sudo cat /var/log/syslog');
while (<$fh>) {
next unless /kernel/;
print $_;
}
close $fh;
$server->shell()
this method works in an X Windowing environment by launching a new terminal window and running an interactive ssh session on the server host. the terminal window is executed in a fork()ed session, so that the rest of the script keeps running. so multitasking ๐
if X Windows isn't running, then the method behaves the same as calling ssh() with no arguments.
the terminal emulator to run is determined by calling the method get_xterm(). ๐
๐ Volume Management Methods ๐
okay bestie so this whole section is about making volumes and then like... herding them around ๐โจ These methods let you create and manage volumes attached to the server, and they supplement the EC2 facilities for creating and attaching EBS volumes โ but with the extra glow-up of being able to format the volumes with a whole variety of filesystems, and mount them wherever you want. iconic behavior honestly.
๐ $volume = $server->provision_volume(%args)
Provision and mount a new volume. If it goes well, you get the volume back as a VM::EC2::Staging::Volume object. slay.
Arguments (with their defaults, no cap):
-nameโ Symbolic name for the desired volume (autogenerated)-fstypeโ Filesystem type for desired volume (ext4)-sizeโ Size for the desired volume in GB (1)-mtptโ Mountpoint for this volume (/mnt/Staging/$name)-mountโ Alias for-mtpt-volume_idโ ID of existing volume to attach & mount (none)-snapshot_idโ ID of existing snapshot to use to create this volume (none)-reuseโ Reuse an existing managed volume of same name (false)-labelโ Disk label to assign during formatting ($name)-uuidโ UUID to assign during formatting (none)
None of the arguments are required, and reasonable defaults will be chosen if they're missing. she's self-sufficient ๐
The -name argument specifies the symbolic name to be assigned to the newly-created staging volume. The name is literally how the staging manager finds this volume later if it gets detached from the server and returned to the available pool. If you don't give a name, an arbitrary one gets autogenerated. ๐ฒ
The -fstype argument specifies the filesystem to be generated on the volume, ext4 by default. The following filesystems are currently supported: ext2, ext3, ext4, xfs, reiserfs, jfs, ntfs, nfs, vfat, msdos. And on top of all those, you can specify a filesystem of "raw" โ which means provision and attach the volume to the server, but do not format it. This is the move for setting up LVM and RAID devices. ๐ Note that if the server does not currently have the package needed to manage the desired filesystem, it will use apt-get to install it. she'll go get it herself, queen.
The -mtpt and -mount arguments (they are equivalent, twins fr ๐ฏ) specify the mount point for the volume on the server filesystem. The default is /mnt/Staging/$name, where $name is the symbolic name provided by -name or autogenerated.
โ ๏ธ No checking is done on the sensibility of the mount point, so pleaseeee try to avoid mounting disks over essential parts of the system. that's a one-way ticket to a broken server, bestie ๐ญ
-volume_id and -snapshot_id instruct the method to construct the staging volume from an existing EBS volume or snapshot.
-volume_idis an EBS volume ID. If provided, the volume must be located in the server's availability zone and be in the"available"state.-snapshot_idis an EBS snapshot ID in the server's region.
In no case will provision_volume() attempt to reformat the resulting volume, even if the -fstype argument is provided. however!! in the case of a volume created from a snapshot, you may specify a -size argument larger than the snapshot and the filesystem will be dynamically resized to fill the requested space. This currently only works with ext2, ext3 and ext4 volumes, and cannot be used to make filesystems smaller. growth only, no shrinking ๐ฆ
If the -reuse argument is true, and a symbolic name is provided in -name, then the method will look for an available staging volume of the same name and mount this at the specified location. If no suitable staging volume is found, then the method will look for a snapshot created earlier from a staging volume of the same name. If neither a suitable volume nor a snapshot is available, then a new volume is provisioned. This is intended to support the following use case of synchronizing a filesystem somewhere to an EBS snapshot:
my $server = $staging_manager->get_server('my_server');
my $volume = $server->provision_volume(-name=>'backup_1',
-reuse => 1,
-fstype => 'ext3',
-size => 10);
$volume->put('fred@gw.harvard.edu:my_music');
$volume->create_snapshot('music_backups');
$volume->delete;
The -label and -uuid arguments are used to set the volume label and UUID during formatting of new filesystems. The default behavior is to create no label and to allow the server to choose an arbitrary UUID. let her cook ๐ณ
๐ธ $volume = $server->add_volume(%args)
This is the same as provision_volume(). that's it, that's the whole thing. an alias living its best life โจ
๐ฆ @volumes = $server->volumes()
Return a list of all the staging volumes attached to this server. Unmanaged volumes, such as the root volume, are not included in the list. sorry root volume, you're not in the group chat ๐
๐
$server->unmount_volume($volume)
Unmount the volume $volume. The volume will remain attached to the server. This method will die with a fatal error if the operation fails. no soft landings here.
See VM::EC2::Staging::Volume->detach() for the recommended way to unmount and detach the volume. iykyk ๐ซถ
๐ $server->detach_volume($volume)
Unmount and detach the volume from the server, waiting until EC2 reports that the detachment completed. A fatal error will occur if the operation fails. she will stand there and wait, patiently, like a good friend holding your bag ๐
โญ $server->mount_volume($volume [,$mountpt])
Mount the volume $volume using the mount information recorded inside the VM::EC2::Staging::Volume object (returned by its mtpt() and mtdev() methods). If the volume has not previously been mounted on this server, then it will be attached to the server and a new mountpoint will be allocated automatically. You can change the mount point by specifying it explicitly in the second argument. so much flexibility, we love options ๐
Here is the recommended way to detach a staging volume from one server and attach it to another:
$server1->detach_volume($volume);
$server2->mount_volume($volume);
This method will die in case of error.
๐ $server->remount_volume($volume)
This is similar to mount_volume(), except that it will fail with a fatal error if the volume was not previously mounted on this server. This is to be used when temporarily unmounting and remounting a volume on the same server:
$server->unmount_volume($volume);
# do some work on the volume
$server->remount_volume($volume)
see her? went away for a sec and came right back. main character energy ๐
๐ $server->delete_volume($volume)
Unmount, detach, and then delete the indicated volume entirely. gone. poof. no take-backs ๐ง
๐ $snap = $server->create_snapshot($volume,$description)
Unmount the volume, snapshot it using the provided description, and then remount the volume. If successful, returns the snapshot. ๐ซ
The snapshot is tagged with the identifying information needed to associate the snapshot with the staging volume. This information then used when creating new volumes from the snapshot with $server->provision_volume(-reuse=>1). the circle of life fr ๐ฑ
Data Copying Methods ๐
okay so these methods are the data-movers. we're copying from one staging server to another, or from your local filesystem to a staging server. it's giving rsync energy. โจ
$result = $server->rsync($src1,$src2,$src3...,$dest)
This is a passthrough to VM::EC2::Staging::Manager->rsync(), and it gives you efficient file-level synchronization (rsync) file-level copying between one or more source locations and a destination location via an ssh tunnel. you can copy among arbitrary combinations of local and remote filesystems, with the caveat that the remote filesystems must be contained on volumes and servers managed by this module (see below for a workaround). ๐
Pass two or more directory paths. the last one is the copy destination, and the earlier ones are the sources. all copying uses the -avz options โ that means recursive directory copying where ownership, modification times, and permissions are preserved, plus compression to save network bandwidth. periodt.
Source paths can be formatted in one of several ways:
/absolute/pathโ copies the contents of/absolute/pathfrom your local machine to the destination. this will create a subdirectory named"path"on the destination disk. add a slash at the end (i.e."/absolute/path/") to avoid creating that subdirectory on the destination disk../relative/pathโ relative paths work the way you expect, and depend on the current working directory. the terminating slash rule applies.$staging_server:/absolute/pathโ pass a staging server object and absolute path to copy the contents of this path to the destination disk. because of string interpolation you can include server objects in quotes:"$my_server:/opt"$staging_server:relative/pathโ this form copies data from paths relative to the remote user's home directory on the staging server. typically not very useful, but supported.$staging_volumeโ pass aVM::EC2::Staging::Volumeto copy the contents of the volume to the destination disk starting at the root of the volume. note that you do not need to have any knowledge of the mount point for this volume in order to copy its contents.$staging_volume:/absolute/pathโ copy a subdirectory of a staging volume to the destination disk. the root of the volume is its top level, regardless of where it is mounted on the staging server. because of string interpolation magic, you can enclose staging volume object names in quotes to construct the path, as in"$picture_volume:/family/vacations/". as in local paths, a terminating slash indicates that the contents of the last directory in the path are to be copied without creating the enclosing directory on the desetination. note that you do not need to have any knowledge of the mount point for this volume in order to copy its contents.$staging_volume:absolute/path$staging_volume/absolute/pathโ these are alternatives to the previous syntax, and all have the same effect as$staging_volume:relative/path. There is no
(and yes, the original manpage literally stops mid-sentence at "There is no". iconic. no notes. ๐)
The same syntax is supported for destination paths, except that it makes no difference whether a path has a trailing slash or not.
Note that neither the source nor destination paths need to reside on this server.
See VM::EC2::Staging::Manager->rsync() for examples and more details.
$server->dd($source_vol=>$dest_vol)
This is a passthrough to VM::EC2::Staging::Manager->dd(), and it does block-level copying of the contents of $source_vol to $dest_vol using dd over an SSH tunnel, where both source and destination volumes are VM::EC2::Staging::Volume objects. the volumes must be attached to a server but not mounted. everything in the volume, including its partition table, gets copied, so you can make an exact image of a disk. iconic.
The volumes do not actually need to reside on this server, but can be attached to any staging server in the zone.
$server->put($source1,$source2,$source3,...,$dest)
Use rsync to copy the indicated source directories into the destination path indicated by $dest. The destination is either a path on the server machine, or a staging volume object mounted on the server (string interpolation is accepted). The sources can be local paths on the machine the perl script is running on, or any of the formats described for rsync().
Examples:
$server1->put("$ENV{HOME}/my_pictures" => '/var/media');
$server1->put("$ENV{HOME}/my_pictures","$ENV{HOME}/my_audio" => '/var/media');
$server1->put("$ENV{HOME}/my_pictures" => "$backup_volume/home_media");
$server1->put("fred@gw.harvard.edu:media/" => "$backup_volume/home_media");
$server->get($source1,$source2,$source3,...,$dest)
Use rsync to copy the indicated source directories into the destination path indicated by $dest. The source directories are either paths on the server, or staging volume(s) mounted on the server (string interpolation to indicate subdirectories on the staging volume also works). The destination can be any of the path formats described for rsync(), including unmanaged hosts that accept ssh login.
Examples:
$server1->get('/var/media' =>"$ENV{HOME}/my_pictures");
$server1->get('/var/media','/usr/bin' => "$ENV{HOME}/test");
$server1->get("$backup_volume/home_media" => "$ENV{HOME}/my_pictures");
$server1->get("$backup_volume/home_media" => "fred@gw.harvard.edu:media/");
Internal Methods ๐ฎ
This section documents internal methods. They are not intended for use by end-user scripts but may be useful to know about during subclassing. There are also additional undocumented methods that begin with a "_" character which you can explore in the source code. lowkey useful if you're subclassing.
$description = $server->volume_description($vol)
This method is called to get the value of the Name tag assigned to new staging volume objects. The current value is "Staging volume for $name created by VM::EC2::Staging::Server."
You will see these names associated with EBS volumes in the AWS console.
($ebs_device,$local_device) = $server->unused_block_device([$major_start])
This method returns an unused block device path. It is invoked when provisioning and mounting new volumes. The behavior is to take the following search path:
/dev/sdf1
/dev/sdf2
...
/dev/sdf15
/dev/sdfg1
...
/dev/sdp15
You can modify the search path slightly by providing a single character major start. For example, to leave all the sdf's free and to start the search at /dev/sdg:
($ebs_device,$local_device) = $server->unused_block_device('g');
The result is a two element list consisting of the unused device name from the perspective of EC2 and the server respectively. The issue here is that on some recent Linux kernels, the EC2 device /dev/sdf1 is known to the server as /dev/xvdf1. This module understands that complication and uses the EC2 block device name when managing EBS volumes, and the kernel block device name when communicating with the server.
$flag = $server->has_key($keyname)
Returns true if the server has a copy of the private key corresponding to $keyname. This is used by the rsync() method to enable server to server data transfers.
$flag = $server->accepts_key($keyname)
Returns true if the server has a copy of the public key part of $keyname in its .ssh/authorized_keys file. This is used by the rsync() method to enable server to server data transfers.
$up = $server->is_up([$new_value])
Get/set the internal is_up() flag, which indicates whether the server is up and running. This is used to cache the results of the ping() method.
$path = $server->default_mtpt($volume)
Given a staging volume, return its default mount point on the server ('/mnt/Staging/'.$volume->name). Can also pass a string corresponding to the volume's name.
$server->info(@message)
Log a message to standard output, respecting the staging manager's verbosity() setting.
Subclassing ๐งฌ
For reasons having to do with the order in which objects are created, VM::EC2::Staging::Server is a wrapper around VM::EC2::Instance rather than a subclass of it. To access the VM::EC2::Instance object, you call the server object's instance() method. In practice this means that to invoke the underlying instance's method for, say, start() you will need to do this:
$server->instance->start();
rather than this:
$server->SUPER::start();
You may subclass VM::EC2::Staging::Server in the usual way.
SEE ALSO ๐
VM::EC2VM::EC2::InstanceVM::EC2::VolumeVM::EC2::Snapshot
AUTHOR โ๏ธ
Lincoln Stein <lincoln.stein@gmail.com>.
Copyright (c) 2011 Ontario Institute for Cancer Research
This package and its accompanying libraries is free software; you can redistribute it and/or modify it under the terms of the GPL (either version 1, or at your option, any later version) or the Artistic License 2.0. Refer to LICENSE for the full license text. In addition, please see DISCLAIMER.txt for disclaimers of warranty.
Source/version: perl v5.38.2 ยท Date: 2024-08-10 ยท Page: VM::EC...Server(3pm) โ that's the whole vibe, bestie. bye! ๐โจ
๐ฆ where this page comes from
- debian trixie: libvm-ec2-perl 1.28-5 ยท Artistic-2.0 OR GPL-1.0-or-later
- ubuntu resolute: libvm-ec2-perl 1.28-5 ยท Artistic-2.0 OR GPL-1.0-or-later
- ubuntu stonking: libvm-ec2-perl 1.28-5 ยท Artistic-2.0 OR GPL-1.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms