mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-10-21 23:28:19 +00:00
06a3f486c7
chtab -d called delEntries on each table that it named without a check that the table opened. A table name that xCAT does not know made chtab die after it had deleted the rows of the tables named before it. The error was "Can't call method delEntries on an undefined value". The delete moves to xCAT::TableUtils->delete_rows, which opens every named table first. When a table does not open, it deletes no row and returns the table name. chtab -d reports that table with the error of the update form.
178 lines
4.7 KiB
Perl
Executable File
178 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::TableUtils;
|
|
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);
|
|
}
|
|
my $missing = xCAT::TableUtils->delete_rows(\%keyhash, @tables_to_del);
|
|
if (defined($missing)) {
|
|
print "Table $missing does not exist.\n";
|
|
exit(1);
|
|
}
|
|
}
|
|
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;
|
|
}
|