[Swift-commit] r3434 - usertools/swift/swiftconfig/bin
noreply at svn.ci.uchicago.edu
noreply at svn.ci.uchicago.edu
Wed Jul 14 06:03:10 CDT 2010
Author: davidk
Date: 2010-07-14 06:03:10 -0500 (Wed, 14 Jul 2010)
New Revision: 3434
Modified:
usertools/swift/swiftconfig/bin/swiftconfig
Log:
interactive editor, auths.default, new split directory structure, better error handling
Modified: usertools/swift/swiftconfig/bin/swiftconfig
===================================================================
--- usertools/swift/swiftconfig/bin/swiftconfig 2010-07-13 19:43:19 UTC (rev 3433)
+++ usertools/swift/swiftconfig/bin/swiftconfig 2010-07-14 11:03:10 UTC (rev 3434)
@@ -1,132 +1,257 @@
#!/usr/bin/perl
-# Find swift configuration files and libraries
-if ( $ENV{'SWIFT_HOME'} ) {
+use Cwd;
+use Cwd qw(abs_path);
+use File::Copy;
+use File::Path qw(remove_tree);
+use 5.010;
+
+my $swifthome = '';
+if ( $ENV{'SWIFT_HOME'} && -e "$ENV{'SWIFT_HOME'}/bin/swift" ) {
$swifthome = $ENV{'SWIFT_HOME'};
}
-else {
- @path = split( '/', which("swift") );
- @path = splice( @path, 0, $#path - 1 );
- $swifthome = join( '/', @path );
+
+my @path = split( '/', abs_path($0) );
+my @path = splice( @path, 0, $#path - 1 );
+my $parent_directory = join( '/', @path );
+
+if ( !$swifthome ) {
+ if ( -e "$parent_directory/bin/swift" ) {
+ $swifthome = $parent_directory;
+ }
+
+ else {
+ @path = split( '/', which("swift") );
+ @path = splice( @path, 0, $#path - 1 );
+ my $tmp = join( '/', @path );
+ if ( -e "$tmp/bin/swift" ) {
+ $swifthome = $tmp;
+ }
+ }
}
-use FindBin;
+use FindBin qw($Bin);
use lib "$FindBin::Bin/../lib/perl"; # Use libraries in $swifthome/lib/perl
use Getopt::Long;
use File::Which qw(which where);
use XML::Simple;
+use Data::Dumper;
# Variables used for translation catalog
-my $host = 'localhost'; # Host name
-my $name = ''; # Translation name
-my $path = "/usr/bin/$name"; # Full path of executable location
-my $status = 'INSTALLED'; # Installation status (not used)
-my $platform = 'INTEL32::LINUX'; # Platform (not used)
-my $profile = 'null'; # Profile entries
-my $tcfile = "$swifthome/etc/tc.data"; # Location of TC file
+my $host = 'localhost'; # Host name
+my $name = ''; # Translation name
+my $path = "/usr/bin/$name"; # Full path of executable location
+my $status = 'INSTALLED'; # Installation status (not used)
+my $platform = 'INTEL32::LINUX'; # Platform (not used)
+my $profile = 'null'; # Profile entries
# Variables used for sites.xml
-my $templatefile = "$swifthome/etc/sites-template.xml"; # Template file
-my $template = ''; # Use template entry
-my $templates = 0; # List all templates
-my $sitesfile = "$swifthome/etc/sites.xml"; # Working sites.xml file
-my $entry = ''; # Name of new entry (pool handle)
-my $gridftp = ''; # Specify gridftp URL
-my $jobuniverse = ''; # Specify jobmanager universe
-my $joburl = ''; # Specify jobmanager URL
-my $jobmajor = ''; # Jobmanager major value
-my $jobminor = ''; # Jobmanager minor value
-my $directory = ''; # Work directory
-my $exprovider = ''; # Execution provider
-my $exmanager = ''; # Execution job manager
-my $exurl = ''; # Execution URL
-my $remove = ''; # Remove entry from sites.xml
-my $modify = ''; # Modify mode
+my $templates = 0; # List all templates
+my $remove = ''; # Remove entry from sites.xml
+my $modify = ''; # Modify mode
+my @validproviders = ( "gt4", "local", "pbs", "condor", "ssh", "coaster" );
+my $keyfile = "$ENV{'HOME'}/.ssh/id_rsa";
# Assign variables from command line options
GetOptions(
- 'host=s' => \$host,
- 'name=s' => \$name,
- 'path=s' => \$path,
- 'status=s' => \$status,
- 'platform=s' => \$platform,
- 'profile=s' => \$profile,
- 'tcfile=s' => \$tcfile,
- 'templatefile=s' => \$templatefile,
- 'add=s' => \$add,
- 'sitesfile=s' => \$sitesfile,
- 'gridftp=s' => \$gridftp,
- 'jobuniverse=s' => \$jobuniverse,
- 'joburl=s' => \$joburl,
- 'jobmajor=i' => \$jobmajor,
- 'jobminor=i' => \$jobminor,
- 'directory=s' => \$directory,
- 'exprovider=s' => \$exprovider,
- 'exmanager=s' => \$exmanager,
- 'exurl=s' => \$exurl,
- 'remove=s' => \$remove,
- 'templates' => \$templates,
- 'modify=s' => \$modify,
- 'key=s' => \$key,
- 'namespace=s' => \$namespace,
- 'value=s' => \$value
+ 'add=s' => \$add,
+ 'remove=s' => \$remove,
+ 'templates' => \$templates,
+ 'modify=s' => \$modify,
+ 'swifthome=s' => \$swifthome,
+ 'sites' => \$sites
);
+# Create a new directory if it does not exist
+sub create_directory {
+ $directory = $_[0];
+ if ( !-d "$directory" ) {
+ mkdir "$directory", 0700
+ or die "Unable to create directory $directory\n";
+ }
+}
+
+# Process keyboard input
+sub getEntry {
+ my ($description, $value, @valid) = @_;
+
+ print "$description [$value]: ";
+ my $newvalue = "";
+ chomp($newvalue = <STDIN>);
+ if ($newvalue) { $value = $newvalue; }
+ my $isvalid = 0;
+
+ if(@valid) {
+ foreach(@valid) {
+ if($_ eq $value){ $isvalid = 1; }
+ }
+ if(!$isvalid) {
+ my $msg = "";
+ foreach(@valid) { $msg .= $_ . " "; }
+ print "Invalid value selected. Please select from: $msg\n";
+ $value = getEntry($description, $value, @valid);
+ }
+ }
+
+ return $value;
+}
+
# Prepare data
-$xml = new XML::Simple();
-$template_data = $xml->XMLin(
- "$templatefile",
- ForceArray => [qw(workdirectory pool profile)],
- KeyAttr => []
-);
-$sites_data = $xml->XMLin(
- "$sitesfile",
- ForceArray => [qw(workdirectory pool profile)],
- KeyAttr => []
-);
-open( TCFILESTREAM, "$tcfile" ) or die("Unable to open tc file $tcfile!");
- at tcdata = <TCFILESTREAM>;
-close(TCFILESTREAM);
+my $xml = new XML::Simple();
+# Create all required directories
+my $dotswift = "$ENV{'HOME'}/.swift";
+create_directory("$ENV{'HOME'}/.ssh");
+create_directory("$dotswift");
+create_directory("$dotswift/sites");
+
+# Determine the template directory
+my @path = split( '/', abs_path($0) );
+my @path = splice( @path, 0, $#path - 1 );
+my $template_directory = join( '/', @path ) . "/etc/sites";
+
+# Add new entry to auths.default
+sub add_ssh_auth
+{
+ my ($entry, $site) = @_;
+
+ # Open authfile
+ my $authfile = "$dotswift/sites/$entry/auth.defaults";
+ create_directory("$dotswift/sites/$entry");
+ if ( -e "$authfile" ) { open( AUTHFILE, "$authfile" ) || die "Unable to open auth file $authfile for reading!\n"; }
+ else { open( AUTHFILE, ">$authfile" ) || die "Unable to open $authfile for writing!\n"; }
+ @authdata = <AUTHFILE>;
+ close(AUTHFILE);
+
+ # Create RSA keypair if needed
+ if ( !-e "$keyfile" ) {
+ system("ssh-keygen -t rsa -f $keyfile");
+ }
+
+ # Get existing username and passphrase values
+ my $username;
+ my $passphrase;
+ foreach (@authdata) {
+ if (/username/i) { (my $blah, $username) = split('=', $_); chomp($username); }
+ if (/passphrase/i) { (my $blah, $passphrase) = split('=', $_); chomp($passphrase); }
+ }
+ if(!$username){ $username = getlogin(); }
+
+ $username = getEntry("Username", $username);
+ $passphrase = getEntry("Passphrase", $passphrase);
+
+ # Remove old auth.defaults if it already exists
+ if(-e "$authfile") {
+ unlink($authfile) || die "Unable to remove $authfile\n";
+ @authdata = ();
+ }
+
+ # Add data to new auth.defaults
+ push( @authdata, "$site.type=key\n" );
+ push( @authdata, "$site.username=$username\n" );
+ push( @authdata, "$site.key=$keyfile\n" );
+ push( @authdata, "$site.passphrase=$passphrase\n" );
+ write_file( $authfile, @authdata );
+}
+
+# Update TC with correct hostname
+sub update_tc_hostname {
+ my ($filename, $host) = @_;
+ # Store TC data
+ open( TCFILESTREAM, "$filename" ) or die("Unable to open tc file $tcfile!");
+ @tcdata = <TCFILESTREAM>;
+ close(TCFILESTREAM);
+
+ foreach $line (@tcdata) {
+ # Ignore comments
+ if ( substr( $line, 0, 1 ) eq '#' ) {
+ next;
+ }
+
+ # Replace old entry with new entry
+ my ( $tmphost, $tmpname, $tmppath, $tmpstatus, $tmpplatform, $tmpprofile ) = split( /\s+/, $line );
+ $tmphost = $host;
+ $line = "$tmphost\t$tmpname\t$tmppath\t$tmpstatus\t$tmpplatform\t$tmpprofile\n";
+ }
+
+ write_file( $filename, @tcdata);
+}
+
# Update XML hash with values from command line
sub update_xml_entry {
- my $xml_data = @_[0];
- my $name = @_[1];
- foreach my $e ( @{ $xml_data->{pool} } ) {
- if ( $name eq $e->{handle} ) {
- $e->{workdirectory}[0] =~ s/\$HOME/$ENV{'HOME'}/;
- if ($gridftp) { $e->{gridftp}{url} = $gridftp; }
- if ($jobuniverse) { $e->{jobmanager}{universe} = $jobuniverse; }
- if ($joburl) { $e->{jobmanager}{url} = $joburl; }
- if ($jobmajor) { $e->{jobmanager}{major} = $jobmajor; }
- if ($jobminor) { $e->{jobmanager}{minor} = $jobminor; }
- if ($directory) { $e->{workdirectory} = [$directory]; }
- if ($exprovider) { $e->{execution}{provider} = $exprovider; }
- if ($exmanager) { $e->{execution}{jobmanager} = $exmanager; }
- if ($exurl) { $e->{execution}{url} = $exurl; }
- if ( $key && $namespace && $value ) {
- my $found = 0;
- foreach my $profile ( @{ $e->{profile} } ) {
- if ( $profile->{key} eq $key ) {
- $profile->{key} = $key;
- $profile->{namespace} = $namespace;
- $profile->{content} = $value;
- $found = 1;
- }
- }
- if ( !$found ) {
- push @{ $e->{profile} },
- {
- key => $key,
- namespace => $namespace,
- content => $value
- };
- }
+ my ($filename) = @_;
+ if ( !-e $filename ) { return 0; }
+ my $entryname = "";
+ my $tcfile = "";
+
+ my $xml_data = $xml->XMLin(
+ $filename,
+ ForceArray => [qw(workdirectory profile)],
+ KeyAttr => []
+ );
+
+ # Renaming
+ if($modify)
+ {
+ $entryname = getEntry("Site Entry Name", $modify);
+ $tcfile = "$dotswift/sites/$modify/tc.data";
+ print "tcfile: $tcfile\n";
+ if($entryname ne $modify) {
+ if(!-d "$dotswift/sites/$entryname" && -d "$dotswift/sites/$modify") {
+ move("$dotswift/sites/$modify", "$dotswift/sites/$entryname") || die "Unable to rename $dotswift/sites/$modify to $dotsite/sites/$entryname";
}
- return $e;
+ $xml_data = $xml->XMLin("$dotswift/sites/$entryname/sites.xml", ForceArray => [qw(workdirectory profile)], KeyAttr => []);
+ $tcfile = "$dotswift/sites/$entryname/tc.data";
}
}
+
+ # Adding
+ if($add){
+ $entryname = getEntry("Site Entry Name", $add);
+ if( -e "$dotswift/sites/$entryname/sites.xml") {
+ die "Entry file for $entryname already exists. Use -modify to change settings\n";
+ }
+ create_directory("$dotswift/sites/$entryname");
+ if(-e "$template_directory/$add/tc.data") { $tcfile = "$template_directory/$add/tc.data"; }
+ elsif (-e "$dotswift/sites/$add/tc.data") { $tcfile = "$dotswift/sites/$add/tc.data"; }
+ copy("$tcfile", "$dotswift/sites/$entryname") || die "Unable to copy $tcfile to $dotswift/sites/$entryname\n";
+ }
+
+ $xml_data->{pool}{handle} = $entryname;
+ if(!-d "$dotswift/sites/$entryname") {
+ create_directory("$dotswift/sites/$entryname");
+ }
+ $filename = "$dotswift/sites/$entryname/sites.xml";
+
+ # Replace values if requested by user
+ $xml_data->{pool}{workdirectory}[0] =~ s/\$HOME/$ENV{'HOME'}/;
+ if ( $xml_data->{pool}{gridftp} ) { $xml_data->{pool}{gridftp} = getEntry( "GridFTP URL", $xml_data->{pool}{gridftp}{url} ); }
+ if ( $xml_data->{pool}{workdirectory} ) { $xml_data->{pool}{workdirectory} = [ getEntry( "Work Directory", $xml_data->{pool}{workdirectory}[0] ) ]; }
+ if ( $xml_data->{pool}{jobmanager} ) {
+ if ( $xml_data->{pool}{jobmanager}{universe} ) { $xml_data->{pool}{jobmanager}{universe} = getEntry( "Job Universe", $xml_data->{pool}{jobmanager}{universe} ); }
+ if ( $xml_data->{pool}{jobmanager}{url} ) { $xml_data->{pool}{jobmanager}{url} = getEntry( "Job Manager URL", $xml_data->{pool}{jobmanager}{url} ); }
+ if ( $xml_data->{pool}{jobmanager}{major} ) { $xml_data->{pool}{jobmanager}{major} = getEntry( "Job Major Number", $xml_data->{pool}{jobmanager}{major} ); }
+ if ( $xml_data->{pool}{jobmanager}{minor} ) { $xml_data->{pool}{jobmanager}{minor} = getEntry( "Job Minor Number", $xml_data->{pool}{jobmanager}{minor} ); }
+ }
+ if ( $xml_data->{pool}{execution} ) {
+ if ( $xml_data->{pool}{execution}{provider} ) { $xml_data->{pool}{execution}{provider} = getEntry( "Execution Provider", $xml_data->{pool}{execution}{provider}, @validproviders); }
+ if ( $xml_data->{pool}{execution}{jobmanager} ) { $xml_data->{pool}{execution}{jobmanager} = getEntry( "Execution Job Manager", $xml_data->{pool}{execution}{jobmanager} ); }
+ if ( $xml_data->{pool}{execution}{url} ) {
+ my $previous_site = $xml_data->{pool}{execution}{url};
+ $xml_data->{pool}{execution}{url} = getEntry( "Execution URL", $xml_data->{pool}{execution}{url} );
+ update_tc_hostname("$tcfile", $xml_data->{pool}{execution}{url});
+ }
+ }
+ if ( $xml_data->{pool}{filesystem} ) {
+ if ( $xml_data->{pool}{filesystem}{provider} ) { $xml_data->{pool}{filesystem}{provider} = getEntry( "Filesystem Provider", $xml_data->{pool}{filesystem}{provider}, @validproviders); }
+ if ( $xml_data->{pool}{filesystem}{url} ) { $xml_data->{pool}{filesystem}{url} = getEntry( "Filesystem URL", $xml_data->{pool}{filesystem}{url} ); }
+ }
+ if ( $xml_data->{pool}{execution}{provider} eq "ssh") {
+ add_ssh_auth($entryname, $xml_data->{pool}{execution}{url});
+ }
+
+ write_file( $filename, $xml->XMLout( $xml_data, RootName => 'config', SuppressEmpty => 1 ) );
}
# Write a file given variable and filename
@@ -137,92 +262,56 @@
close(TEMPFILESTREAM);
}
+# Print all files in a directory
+sub print_directory {
+ my ($template_directory) = @_;
+ chdir($template_directory) || die "Unable to change directories to $template_directory\n";
+ my @files = <*>;
+ foreach $file(@files)
+ {
+ (my $basename, my $ext) = split(/\./, $file);
+ my @path = split( '/', $basename);
+ print "$basename\n";
+ }
+}
+
# If a template is specified, find the correct one and modify as needed
if ($add) {
- my $data = update_xml_entry( $template_data, $add );
-
- # Modify existing entry
- my $isfound = 0;
- foreach my $e ( @{ $sites_data->{pool} } ) {
- if ( $add eq $e->{handle} ) {
- $e = $data;
- $isfound = 1;
- }
- }
-
- # Add new entry
- if ( !$isfound ) {
- push @{ $sites_data->{pool} }, $data;
- }
-
- # Write to sites file
- write_file( $sitesfile, $xml->XMLout( $sites_data, RootName => 'config' ) );
+ my $data = 0;
+ $data = update_xml_entry("$template_directory/$add/sites.xml");
+ if ( $data == 0 ) { $data = update_xml_entry("$dotswift/sites/$add/sites.xml"); }
+ if ( $data == 0 ) { die "Unable to find template for $add\n"; }
}
# Remove an entry
if ($remove) {
- # Look first for a site to remove
- $isfound = 0;
+ if(!-d "$dotswift/sites/$remove") {
+ "Unable to find site entry for $remove\n";
+ }
- foreach my $e ( @{ $sites_data->{pool} } ) {
- if ( $remove eq $e->{handle} ) {
- undef $e;
- $isfound = 1;
- }
- }
-
- # Write to sites file
- if ($isfound) {
- write_file(
- $sitesfile,
- $xml->XMLout(
- $sites_data,
- RootName => 'config',
- SuppressEmpty => 1
- )
- );
- }
-
- # If no site found, check for a TC entry
- else {
- foreach $line (@tcdata) {
-
- # Ignore comments
- if ( substr( $line, 0, 1 ) eq '#' ) {
- next;
- }
- ( $tmphost, $tmpname, @junk ) = split( /\s+/, $line );
-
- # Replace old entry with new entry
- if ( $remove eq $tmpname ) {
- $line = "";
- }
- }
- write_file( $tcfile, @tcdata );
- }
+ remove_tree("$dotswift/sites/$remove") || die "Unable to remove directory $dotswift/sites/$remove\n";
}
# List all available templates
if ($templates) {
- foreach my $e ( @{ $template_data->{pool} } ) {
- print $e->{handle} . "\n";
- }
+ print_directory($template_directory);
}
+# List all user-added sites
+if($sites) {
+ print_directory("$dotswift/sites");
+}
+
# Modify a site entry
if ($modify) {
- my $data = update_xml_entry( $sites_data, $modify );
- # Modify entry if one already exists
- foreach my $e ( @{ $sites_data->{pool} } ) {
- if ( $modify eq $e->{handle} ) {
- $e = $data;
- }
+ if(!-e "$dotswift/sites/$modify/sites.xml") {
+ die "Unable to find entry for $modify\n";
}
- write_file( $sitesfile,
- $xml->XMLout( $sites_data, RootName => 'config', SuppressEmpty => 1 ) );
+ my $data = update_xml_entry( "$dotswift/sites/$modify/sites.xml" );
+
}
# Add or modify a TC entry
@@ -252,6 +341,7 @@
}
__END__
+
=head1 NAME
swiftconfig - Utility for managing Swift configuration
@@ -269,35 +359,9 @@
General operations:
-add sitename add a site from template
-remove site removes a site from sites.xml
- -remove command removes a command from the catalog
-templates display all available sites in template
-modify site Specifies the name of a site to modify
-Translation catalog settings:
- -host hostname hostname of the translation catalog entry
- -name name translation name
- -path path full pathname to location of program
- -status status installation status (deprecated)
- -profile setting define the profile value for an entry
- -tcfile filename explicitly specify a translation file
-
-Sites settings:
- -templatefile file explicitly set the template file to use
- -sitesfile file explicitly set the sites file to use
- -gridftp GridFTPURL GridFTP URL
- -jobuniverse universe job manager universe
- -joburl URL job manager URL
- -jobmajor major job mager number
- -jobminor minor job minor number
- -directory dir work directory
- -exprovider name execution provider
- -exmanager name execution job manager
- -exurl URL execution URL
- -key key profile key
- -value value profile value
- -namespace name profile namespace
-
-
=head1 EXAMPLES
List all templates available for adding
@@ -307,20 +371,11 @@
swiftconfig -add teraport
Modify the work directory of a site
- swiftconfig -modify teraport -directory /var/tmp
+ swiftconfig -modify teraport
Remove a site
swiftconfig -remove teraport
-Add a new command to translation catalog
- swiftconfig -name convert -path /usr/local/bin/convert
-
-Modify an existing command in the translation catalog
- swiftconfig -name convert -path /usr/bin/convert
-
-Remove a command from the translation catalog
- swiftconfig -remove convert
-
=head1 CAVEATS
Swiftconfig will attempt to automatically determine the location of swift configuration files. It first checks for an environment variable called $SWIFT_HOME. If that is not found, it will look for the location of "swift" in the path, and try to find the configuration files from there. This default behavior can be overwridden by manually specifying the location of files with -templatefile, -sitesfile, and -tcfile.
More information about the Swift-commit
mailing list