mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 19:32:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			177 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env perl
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| use xCAT::Table;
 | |
| use xCAT::NodeRange;
 | |
| use Getopt::Long;
 | |
| 
 | |
| use strict;
 | |
| 
 | |
| #This or something like this must always be available and not depend on server
 | |
| #Otherwise, can't set things to let server run in the first place
 | |
| #
 | |
| 
 | |
| sub usage {
 | |
|     print "Usage:\n";
 | |
|     print " To add or update rows for tables:
 | |
|    chtab keycolname=keyvalue[,keycolname=keyvalue...] tablename.colname=newvalue [tablename.colname=newvalue...]\n";
 | |
|     print " To delete rows from tables:
 | |
|    chtab -d|--delete keycolname=keyvalue[,keycolname=keyvalue...] tablename [tablename...]\n";
 | |
|     print " To display usage and other information:
 | |
|    chtab [-h|--help|-v|--Version]\n\n";
 | |
|     print "   -d|--delete  Delete the rows from a list of tables.
 | |
|    -v|--version Display the version of this command.
 | |
|    -h|--help    Display this usage information.
 | |
|    keycolname=keyvalue   a column name-and-value pair that identifies the rows in a table to be changed.
 | |
|    tablename.colname=newvalue    the new value for the specified row and column of the table.\n";
 | |
| }
 | |
| 
 | |
| my %tables;
 | |
| 
 | |
| # options can be bundled up like -vV
 | |
| Getopt::Long::Configure("bundling");
 | |
| $Getopt::Long::ignorecase = 0;
 | |
| 
 | |
| # parse the options
 | |
| if (!GetOptions(
 | |
|         'd|delete'  => \$::DELETE,
 | |
|         'h|help'    => \$::HELP,
 | |
|         'v|version' => \$::VERSION,))
 | |
| {
 | |
|     &usage;
 | |
|     exit(1);
 | |
| }
 | |
| 
 | |
| # display the usage if -h or --help is specified
 | |
| if ($::HELP) { &usage; exit(0); }
 | |
| 
 | |
| # display the version statement if -v or --verison is specified
 | |
| if ($::VERSION)
 | |
| {
 | |
|     my $version = xCAT::Utils->Version();
 | |
|     print "chtab $version\n";
 | |
|     exit(0);
 | |
| }
 | |
| 
 | |
| my $target = shift @ARGV;
 | |
| unless ($target) {
 | |
|     usage;
 | |
|     exit(1);
 | |
| }
 | |
| 
 | |
| my $current_userid = getpwuid($>);
 | |
| if ($current_userid ne "root")
 | |
| {
 | |
|     print "WARNING: chtab bypasses xcatd and does not enforce xCAT policy tables. Consider using tabch instead.\n";
 | |
| }
 | |
| 
 | |
| my %keyhash = ();
 | |
| my @keypairs = split(/,/, $target);
 | |
| if ($keypairs[0] !~ /([^\.\=]+)\.([^\.\=]+)\=(.+)/) {
 | |
|     foreach (@keypairs) {
 | |
|         m/(.*)=(.*)/;
 | |
|         my $key = $1;
 | |
|         my $val = $2;
 | |
|         if (!defined($key) || !defined($val)) {
 | |
|             print "Incorrect argument \"$_\".\n";
 | |
|             usage;
 | |
|             exit(1);
 | |
|         }
 | |
|         $keyhash{$key} = $val;
 | |
|     }
 | |
| } else {
 | |
|     unshift(@ARGV, $target);
 | |
| }
 | |
| 
 | |
| 
 | |
| if ($::DELETE) {
 | |
| 
 | |
|     #delete option is specified
 | |
|     my @tables_to_del = @ARGV;
 | |
|     if (@tables_to_del == 0) {
 | |
|         print "Missing table name.\n";
 | |
|         usage;
 | |
|         exit(1);
 | |
|     }
 | |
|     for (@tables_to_del) {
 | |
|         $tables{$_} = xCAT::Table->new($_, -create => 1, -autocommit => 0);
 | |
|         $tables{$_}->delEntries(\%keyhash);
 | |
|         $tables{$_}->commit;
 | |
|     }
 | |
| }
 | |
| else {
 | |
|     #update or create option
 | |
|     my %tableupdates;
 | |
|     for (@ARGV) {
 | |
|         my $temp;
 | |
|         my $table;
 | |
|         my $column;
 | |
|         my $value;
 | |
| 
 | |
|         ($table, $temp) = split('\.', $_, 2);
 | |
| 
 | |
|         #try to create the entry if it doesn't exist
 | |
|         unless ($tables{$table}) {
 | |
|             my $tab = xCAT::Table->new($table, -create => 1, -autocommit => 0);
 | |
|             if ($tab) {
 | |
|                 $tables{$table} = $tab;
 | |
|             } else {
 | |
|                 print "Table $table does not exist.\n";
 | |
|                 exit(1);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #splice assignment
 | |
|         if (grep /\+=/, $temp) {
 | |
|             ($column, $value) = split('\+=', $temp, 2);
 | |
| 
 | |
|             #grab the current values to check against
 | |
|             my ($attrHash) = $tables{$table}->getAttribs(\%keyhash, $column);
 | |
|             my @existing = split(",", $attrHash->{$column});
 | |
| 
 | |
|             #if it has values, merge the new and old ones together so no dupes
 | |
|             if (@existing) {
 | |
|                 my @values = split(",", $value);
 | |
|                 my %seen   = ();
 | |
|                 my @uniq   = ();
 | |
|                 my $item;
 | |
| 
 | |
|                 foreach $item (@existing, @values) {
 | |
|                     unless ($seen{$item}) {
 | |
| 
 | |
|                         # if we get here, we have not seen it before
 | |
|                         $seen{$item} = 1;
 | |
|                         push(@uniq, $item);
 | |
|                     }
 | |
|                 }
 | |
|                 $value = join(",", @uniq);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #normal non-splicing assignment
 | |
|         else {
 | |
|             ($column, $value) = split("=", $temp, 2);
 | |
|         }
 | |
| 
 | |
|         $tableupdates{$table}{$column} = $value;
 | |
|     }
 | |
| 
 | |
|     #commit all the changes
 | |
|     foreach (keys %tables) {
 | |
|         if (exists($tableupdates{$_})) {
 | |
|             my $rc = $tables{$_}->setAttribs(\%keyhash, \%{ $tableupdates{$_} });
 | |
|             if ($rc) {
 | |
|                 $::exitcode = 1;
 | |
|             }
 | |
|         }
 | |
|         $tables{$_}->commit;
 | |
|     }
 | |
| }
 | |
| if ($::exitcode) {
 | |
|     exit $::exitcode;
 | |
| }
 |