1
0
mirror of synced 2026-04-26 12:26:54 +00:00

Added stub implementation for this command. Works for loopback + ext3

This commit is contained in:
Steve Kemp
2007-12-05 00:03:17 +00:00
parent 154d444f11
commit de9944f006

View File

@@ -1,42 +1,437 @@
#!/usr/bin/perl
#!/usr/bin/perl -w
=head1 NAME
xen-resize-guest - Resize a loopback-based xen guest.
=head1 SYNOPSIS
xen-resize-guest [options]
Help Options:
--help Show help information.
--manual Read the manual for this script.
--version Show the version information and exit.
--verbose Show diagnostic output.
General Options:
--add Specify the amount of space to add, e.g. --add=1gb
--dir Specify the path to the loopback image root.
--force Force the resize to happen without a last-chance delay.
--hostname Specify the hostname of the guest to resize.
=cut
=head1 OPTIONS
=over 8
=item B<--add>
Specify the amount of storage to add to the primary disk.
=item B<--help>
Show help information.
=item B<--hostname>
Specify the hostname to delete.
=item B<--manual>
Read the manual for this script.
=item B<--version>
Show the version number and exit.
=back
=cut
=head1 DESCRIPTION
=cut
=head1 AUTHOR
Steve
--
http://www.steve.org.uk/
=cut
=head1 LICENSE
Copyright (c) 2005-2007 by Steve Kemp. All rights reserved.
This module is free software;
you can redistribute it and/or modify it under
the same terms as Perl itself.
The LICENSE file contains the full text of the license.
=cut
use strict;
use English;
use Env;
use Getopt::Long;
use Pod::Usage;
use Text::Template;
#
# Get domain name.
#
#
# Get disk increase amount.
#
#
# Ensure guest isn't running.
# Configuration values read from the command line, or configuration file.
#
my %CONFIG;
#
# If LVM:
# lvmresize
#
# Release number.
#
my $RELEASE = '3.7';
#
# If disk:
# dd...
# Read the global configuration file.
#
readConfigurationFile( "/etc/xen-tools/xen-tools.conf" );
#
# Parse the command line arguments.
#
parseCommandLineArguments();
#
# Validate our arguments.
#
testArguments();
#
# The path to the file, or device, to resize.
#
my $path = undef;
if ( $CONFIG{'dir'} )
{
#
# Make sure we can find the disk
#
$path = $CONFIG{'dir'} . "/domains/" . $CONFIG{'hostname'} . "/disk.img";
if ( ! -e $path )
{
print <<EOF;
The disk image for the guest domain $CONFIG{'hostname'} was not found
where we expected it to be:
$path
Please check and try again, or report this as a bug.
EOF
exit;
}
#
# Ensure the file is an ext3 filesystem.
#
my $type = `file $path`;
if ( $type !~ /ext3/ )
{
print "Filesystem type is not understood.\n";
print "We only handle ext3 right now!\n";
print "Aborting\n";
exit;
}
#
# OK we have the size, we have the image.
#
# Resize with DD
#
print "Preparing to resize image: $path\n";
#
# Allow panic
#
if ( !$CONFIG{'force'} )
{
foreach my $i ( 1 .. 10 )
{
my $delay = 10 - $i;
print "Sleeping for $delay seconds to allow cancel\n";
sleep 1;
}
}
print "DO NOT INTERRUPT\n";
my $cmd = "dd if=/dev/zero bs=1M count=$CONFIG{'add'}k >> $path";
system( $cmd );
}
elsif ( $CONFIG{'lvm'} )
{
print "LVM isn't supported yet!\n";
exit;
}
else
{
print "Unknown storage type. (Neither LVM nor loopback.)\n";
exit;
}
#
# Check filesystem.
#
print "Checking filesystem\n";
system( "fsck.ext3 -f $path" );
#
# Run ext3resize.
#
print "Resizing in place\n";
system( "resize2fs $path" );
#
# Job done.
#
#
print "All done\n";
=begin doc
Read the configuration file specified.
=end doc
=cut
sub readConfigurationFile
{
my ($file) = ( @_ );
open( FILE, "<", $file ) or die "Cannot read file '$file' - $!";
my $line = "";
while (defined($line = <FILE>) )
{
chomp $line;
if ($line =~ s/\\$//)
{
$line .= <FILE>;
redo unless eof(FILE);
}
# Skip lines beginning with comments
next if ( $line =~ /^([ \t]*)\#/ );
# Skip blank lines
next if ( length( $line ) < 1 );
# Strip trailing comments.
if ( $line =~ /(.*)\#(.*)/ )
{
$line = $1;
}
# Find variable settings
if ( $line =~ /([^=]+)=([^\n]+)/ )
{
my $key = $1;
my $val = $2;
# Strip leading and trailing whitespace.
$key =~ s/^\s+//;
$key =~ s/\s+$//;
$val =~ s/^\s+//;
$val =~ s/\s+$//;
# command expansion?
if ( $val =~ /(.*)`([^`]+)`(.*)/ )
{
# store
my $pre = $1;
my $cmd = $2;
my $post = $3;
# get output
my $output = `$cmd`;
chomp( $output );
# build up replacement.
$val = $pre . $output . $post;
}
# Store value.
$CONFIG{ $key } = $val;
}
}
close( FILE );
}
=begin doc
Parse the command line arguments this script was given.
=end doc
=cut
sub parseCommandLineArguments
{
my $HELP = 0;
my $MANUAL = 0;
my $VERSION = 0;
#
# Parse options.
#
GetOptions(
# Misc. options
"add=s", \$CONFIG{'add'},
"dir=s", \$CONFIG{'dir'},
"hostname=s", \$CONFIG{'hostname'},
"force", \$CONFIG{'force'},
# Help options
"help", \$HELP,
"manual", \$MANUAL,
"verbose", \$CONFIG{'verbose'},
"version", \$VERSION
);
pod2usage(1) if $HELP;
pod2usage(-verbose => 2 ) if $MANUAL;
if ( $VERSION )
{
print( "xen-resize-guest release $RELEASE\n" );
exit;
}
}
=begin doc
Test our arguments are complete.
=end doc
=cut
sub testArguments
{
#
# Make sure we received a hostname.
#
if ( !$CONFIG{'hostname'} )
{
print <<EOF;
A hostname is mandatory!
Please specify one with --hostname=some.host.name
EOF
exit;
}
#
# Make sure we received a size.
#
if ( !$CONFIG{'add'} )
{
print <<EOF;
Please specify a size to increase the guest by:
--add=1Gb -> Increase the size of the disk image by 1Gb.
--add=1 -> Increase the size of the disk image by 1Mb.
EOF
exit;
}
#
# Now make sure we have a loopback option.
#
if ( !$CONFIG{'dir'} )
{
print <<EOF;
We have not been given a directory for the xen images.
Please specify one via --dir=/path/to/images
EOF
exit;
}
#
# Make sure the guest isn't running
#
if ( xenRunning( $CONFIG{'hostname'} ) )
{
print "The guest $CONFIG{'hostname'} appears to be running!\n";
exit;
}
#
# Convert from Gb -> Mb;
#
if ( $CONFIG{'add'} =~ /^([0-9.]+)Gb*$/i )
{
$CONFIG{'add'} = $1 * 1024;
}
if ( $CONFIG{'add'} =~ /^([0-9.]+)Mb*$/i )
{
$CONFIG{'add'} = $1;
}
}
=begin doc
Test to see if the given instance is running.
=end doc
=cut
sub xenRunning
{
my( $hostname ) = (@_ );
my $running = 0;
open( CMD, "xm list $hostname 2>/dev/null |")
or die "Failed to run 'xm list $hostname'";
while( <CMD> )
{
my $line = $_;
$running = 1 if ( $line =~ /\Q$hostname\E/ )
}
close( CMD );
return( $running );
}