2007-03-11 16:37:41 by steve
Added script to create new NFS-root instances.
This commit is contained in:
6
Makefile
6
Makefile
@@ -8,7 +8,7 @@
|
||||
# --
|
||||
# http://www.steve.org.uk/
|
||||
#
|
||||
# $Id: Makefile,v 1.94 2007-02-23 21:58:12 steve Exp $
|
||||
# $Id: Makefile,v 1.95 2007-03-11 16:37:42 steve Exp $
|
||||
|
||||
|
||||
#
|
||||
@@ -87,6 +87,7 @@ fixup-perms:
|
||||
chmod 755 hooks/common.sh
|
||||
chmod 644 etc/xen-tools.conf
|
||||
chmod 644 etc/xm.tmpl
|
||||
chmod 644 etc/xm-nfs.tmpl
|
||||
chmod 644 misc/xm misc/xen-tools misc/README
|
||||
|
||||
#
|
||||
@@ -99,6 +100,7 @@ install-etc:
|
||||
-mkdir -p ${prefix}/etc/xen-tools/role.d/
|
||||
cp etc/xen-tools.conf ${prefix}/etc/xen-tools/
|
||||
cp etc/xm.tmpl ${prefix}/etc/xen-tools/
|
||||
cp etc/xm-nfs.tmpl ${prefix}/etc/xen-tools/
|
||||
-mkdir -p ${prefix}/etc/bash_completion.d
|
||||
cp misc/xen-tools ${prefix}/etc/bash_completion.d/
|
||||
cp misc/xm ${prefix}/etc/bash_completion.d/
|
||||
@@ -110,6 +112,7 @@ install-etc:
|
||||
install-bin:
|
||||
mkdir -p ${prefix}/usr/bin
|
||||
cp bin/xen-create-image ${prefix}/usr/bin
|
||||
cp bin/xen-create-nfs ${prefix}/usr/bin
|
||||
cp bin/xt-customize-image ${prefix}/usr/bin
|
||||
cp bin/xt-install-image ${prefix}/usr/bin
|
||||
cp bin/xt-create-xen-config ${prefix}/usr/bin
|
||||
@@ -117,6 +120,7 @@ install-bin:
|
||||
cp bin/xen-list-images ${prefix}/usr/bin
|
||||
cp bin/xen-update-image ${prefix}/usr/bin
|
||||
chmod 755 ${prefix}/usr/bin/xen-create-image
|
||||
chmod 755 ${prefix}/usr/bin/xen-create-nfs
|
||||
chmod 755 ${prefix}/usr/bin/xt-customize-image
|
||||
chmod 755 ${prefix}/usr/bin/xt-install-image
|
||||
chmod 755 ${prefix}/usr/bin/xt-create-xen-config
|
||||
|
||||
359
bin/xen-create-nfs
Executable file
359
bin/xen-create-nfs
Executable file
@@ -0,0 +1,359 @@
|
||||
#!/usr/bin/perl -w
|
||||
#
|
||||
# TODO: Document.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use English;
|
||||
use Env;
|
||||
use Getopt::Long;
|
||||
use Pod::Usage;
|
||||
use Text::Template;
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Configuration values read from the command line.
|
||||
#
|
||||
# We do not need to read any configuration file.
|
||||
#
|
||||
my %CONFIG;
|
||||
|
||||
#
|
||||
# Default options
|
||||
#
|
||||
$CONFIG{'template'} = '/etc/xen-tools/xm-nfs.tmpl';
|
||||
|
||||
|
||||
#
|
||||
# Release number.
|
||||
#
|
||||
my $RELEASE = '3.1';
|
||||
|
||||
|
||||
# store version number away.
|
||||
$CONFIG{'xen_tools_version'} = $RELEASE;
|
||||
|
||||
|
||||
#
|
||||
# Read the global configuration file.
|
||||
#
|
||||
readConfigurationFile( "/etc/xen-tools/xen-tools.conf" );
|
||||
|
||||
|
||||
#
|
||||
# Parse the command line arguments.
|
||||
#
|
||||
parseCommandLineArguments();
|
||||
|
||||
|
||||
#
|
||||
# Validate our arguments.
|
||||
#
|
||||
testArguments();
|
||||
|
||||
|
||||
#
|
||||
# Create the image.
|
||||
#
|
||||
if ( -e "/etc/xen/$CONFIG{'hostname'}.cfg" )
|
||||
{
|
||||
die "Configuration file for $CONFIG{'hostname'} already exists"
|
||||
unless( $CONFIG{'force'} );
|
||||
}
|
||||
|
||||
#
|
||||
# If we've been given any administrators then set them up.
|
||||
#
|
||||
if ( $CONFIG{'admins'} )
|
||||
{
|
||||
setupAdminUsers();
|
||||
}
|
||||
|
||||
#
|
||||
# Now create the NFS configuration file.
|
||||
#
|
||||
createNewConfigurationFile();
|
||||
|
||||
|
||||
|
||||
#
|
||||
# All done.
|
||||
#
|
||||
exit;
|
||||
|
||||
|
||||
|
||||
=begin doc
|
||||
|
||||
Read the specified configuration file, and update our global configuration
|
||||
hash with the values found in it.
|
||||
|
||||
=end doc
|
||||
|
||||
=cut
|
||||
|
||||
sub readConfigurationFile
|
||||
{
|
||||
my ($file) = ( @_ );
|
||||
|
||||
# Don't read the file if it doesn't exist.
|
||||
return if ( ! -e $file );
|
||||
|
||||
|
||||
my $line = "";
|
||||
|
||||
open( FILE, "<", $file ) or die "Cannot read file '$file' - $!";
|
||||
|
||||
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+$//;
|
||||
|
||||
# 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(
|
||||
|
||||
# Networking options
|
||||
"dhcp", \$CONFIG{'dhcp'},
|
||||
"gateway=s", \$CONFIG{'gateway'},
|
||||
"broadcast=s", \$CONFIG{'broadcast'},
|
||||
"ip=s", \$CONFIG{'ip'},
|
||||
"netmask=s", \$CONFIG{'netmask'},
|
||||
"hostname=s", \$CONFIG{'hostname'},
|
||||
"memory=s", \$CONFIG{'memory'},
|
||||
"mac=s", \$CONFIG{'mac'},
|
||||
|
||||
# NFS options.
|
||||
"nfs_server=s", \$CONFIG{'nfs_server'},
|
||||
"nfs_root=s", \$CONFIG{'nfs_root'},
|
||||
|
||||
# Misc. options
|
||||
"admins=s", \$CONFIG{'admins'},
|
||||
"force", \$CONFIG{'force'},
|
||||
"template=s", \$CONFIG{'template'},
|
||||
|
||||
# Help options
|
||||
"help", \$HELP,
|
||||
"manual", \$MANUAL,
|
||||
"version", \$VERSION
|
||||
);
|
||||
|
||||
pod2usage(1) if $HELP;
|
||||
pod2usage(-verbose => 2 ) if $MANUAL;
|
||||
|
||||
|
||||
if ( $VERSION )
|
||||
{
|
||||
my $REVISION = '$Revision: 1.1 $';
|
||||
if ( $REVISION =~ /1.([0-9.]+) / )
|
||||
{
|
||||
$REVISION = $1;
|
||||
}
|
||||
|
||||
logprint( "xen-create-image release $RELEASE - CVS: $REVISION\n" );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
=head2 testArguments
|
||||
|
||||
Test that our arguments make sense.
|
||||
|
||||
=cut
|
||||
|
||||
sub testArguments
|
||||
{
|
||||
#
|
||||
# Hostname is mandatory
|
||||
#
|
||||
die "No hostname" unless( $CONFIG{'hostname'} );
|
||||
|
||||
my @network = qw/ ip gateway netmask /;
|
||||
|
||||
#
|
||||
# If DHCP then all the other options aren't needed
|
||||
#
|
||||
if ( $CONFIG{'dhcp'} )
|
||||
{
|
||||
foreach my $f ( @network )
|
||||
{
|
||||
delete( $CONFIG{ $f } );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach my $f ( @network )
|
||||
{
|
||||
die "Missing --$f" unless( $CONFIG{$f} );
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# We need an NFS server + root
|
||||
#
|
||||
die "Missing NFS server." unless( $CONFIG{'nfs_server'} );
|
||||
die "Missing NFS root." unless( $CONFIG{'nfs_root'} );
|
||||
|
||||
|
||||
# All OK.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
=begin doc
|
||||
|
||||
This routine is designed to ensure that any users specified with
|
||||
the --admins flag are setup as administrators of the new instance.
|
||||
|
||||
=end doc
|
||||
|
||||
=cut
|
||||
|
||||
sub setupAdminUsers
|
||||
{
|
||||
#
|
||||
# If we're not root we can't modify users.
|
||||
#
|
||||
return if ( $EFFECTIVE_USER_ID != 0 );
|
||||
|
||||
#
|
||||
# If we don't have a sudoers file then we'll also ignore this.
|
||||
#
|
||||
return if ( ! -e "/etc/sudoers" );
|
||||
|
||||
#
|
||||
# Find the path to the xen-login-shell
|
||||
#
|
||||
my $shell = undef;
|
||||
$shell = "/usr/bin/xen-login-shell" if ( -x "/usr/bin/xen-login-shell" );
|
||||
$shell = "/usr/local/bin/xen-login-shell" if ( -x "/usr/bin/local/xen-login-shell" );
|
||||
|
||||
return if ( !defined( $shell ) );
|
||||
|
||||
|
||||
#
|
||||
# For each user make sure they exist, and setup the
|
||||
# login shell for them.
|
||||
#
|
||||
foreach my $user ( split( /,/, $ENV{'admins'} ) )
|
||||
{
|
||||
# Strip leading and trailing whitespace.
|
||||
$user =~ s/^\s+//;
|
||||
$user =~ s/\s+$//;
|
||||
|
||||
# Ignore root
|
||||
next if ( $user =~ /^root$/i );
|
||||
|
||||
# Does the user exist?
|
||||
if ( getpwnam($user) )
|
||||
{
|
||||
# Change shell.
|
||||
$CONFIG{'verbose'} && print "Changing shell for $user: $shell\n";
|
||||
system( "chsh", "-s", $shell, $user );
|
||||
}
|
||||
else
|
||||
{
|
||||
# Add a new user.
|
||||
$CONFIG{'verbose'} && print "Adding new user: $user\n";
|
||||
system( "useradd", "-s", $shell, $user );
|
||||
}
|
||||
|
||||
#
|
||||
# Add the entry to /etc/sudoers.
|
||||
#
|
||||
open( SUDOERS, ">>", "/etc/sudoers" ) or warn "Failed to add user to sudoers file : $user - $!";
|
||||
print SUDOERS "$user ALL = NOPASSWD: /usr/sbin/xm, /usr/bin/xen-create-image\n";
|
||||
close( SUDOERS );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
=head2 createNewConfigurationFile
|
||||
|
||||
Create the configuration file for the specified image.
|
||||
|
||||
=cut
|
||||
|
||||
sub createNewConfigurationFile
|
||||
{
|
||||
die "Template file missing: $CONFIG{'template'}" unless( -e $CONFIG{'template'} );
|
||||
|
||||
#
|
||||
# Load the template.
|
||||
#
|
||||
my $template = new Text::Template( TYPE => 'FILE',
|
||||
SOURCE => $CONFIG{'template'} );
|
||||
|
||||
my $result = $template->fill_in( HASH => \%CONFIG );
|
||||
|
||||
#
|
||||
# The file we'll write to.
|
||||
#
|
||||
my $file = "/etc/xen/$CONFIG{'hostname'}.cfg";
|
||||
|
||||
#
|
||||
# Output the configuration file.
|
||||
#
|
||||
open( FILE, ">", $file ) or die "Failed to write to $file - $!";
|
||||
print FILE $result;
|
||||
close( FILE );
|
||||
}
|
||||
73
etc/xm-nfs.tmpl
Normal file
73
etc/xm-nfs.tmpl
Normal file
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# Configuration file for the Xen NFS-root instance {$hostname}.
|
||||
# Created by xen-tools {$xen_tools_version} on { scalar localtime }.
|
||||
#
|
||||
|
||||
#
|
||||
# Common stuff.
|
||||
#
|
||||
{ if ( $kernel )
|
||||
{
|
||||
$OUT.= "kernel = '$kernel'";
|
||||
}
|
||||
}
|
||||
{ if ( $initrd )
|
||||
{
|
||||
$OUT.= "ramdisk = '$initrd'";
|
||||
}
|
||||
}
|
||||
memory = '{$memory}'
|
||||
|
||||
|
||||
# Name
|
||||
name = '{$hostname}'
|
||||
hostname = '{$hostname}'
|
||||
|
||||
#
|
||||
# Networking
|
||||
#
|
||||
{ if ( $dhcp )
|
||||
{
|
||||
$OUT .= "dhcp = 'dhcp'\n";
|
||||
|
||||
# Setup the mac address, if present.
|
||||
my $m = '';
|
||||
if ( $mac )
|
||||
{
|
||||
$m = "mac=$mac"
|
||||
}
|
||||
|
||||
$OUT .= "vif = [ '$m' ]";
|
||||
}
|
||||
else
|
||||
{
|
||||
#
|
||||
# Setup the mac address, if present.
|
||||
#
|
||||
my $m = '';
|
||||
if ( $mac )
|
||||
{
|
||||
$m = ",mac=$mac"
|
||||
}
|
||||
|
||||
$OUT .= "vif = [ 'ip=$ip";
|
||||
$OUT .= "$m' ]\n";
|
||||
|
||||
$OUT .= "ip = '$ip'\n";
|
||||
$OUT .= "netmask = '$netmask'\n";
|
||||
$OUT .= "broadcast = '$broadcast'\n";
|
||||
$OUT .= "gateway = '$gateway'\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# NFS options
|
||||
nfs_server = '{ $nfs_server }'
|
||||
nfs_root = '{ $nfs_root }'
|
||||
root = '/dev/nfs'
|
||||
|
||||
{ if ( $admins )
|
||||
{
|
||||
$OUT .= "xen_shell = '$admins'\n";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user