#! /usr/bin/perl # # slxconfig - # # (c) 2006 - OpenSLX.com # # Oliver Tappe # use strict; my $abstract = q[ slxconfig This script can be used to display or change the OpenSLX configuration database. You can create systems that use a specific vendor-OS and you can create clients for these systems, too. ]; use Getopt::Long qw(:config pass_through); use Pod::Usage; # add the folder this script lives in and the lib-folder to perl's # search path for modules: use FindBin; use lib "$FindBin::RealBin"; use lib "$FindBin::RealBin/../lib"; use lib "$FindBin::RealBin/../config-db"; # development path to config-db use OpenSLX::Basics; use OpenSLX::ConfigDB; use OpenSLX::DBSchema; my ( $helpReq, $manReq, $verbose, $versionReq, ); GetOptions( 'help|?' => \$helpReq, 'man' => \$manReq, 'verbose' => \$verbose, 'version' => \$versionReq, ) or pod2usage(2); pod2usage(-msg => $abstract, -verbose => 0, -exitval => 1) if $helpReq; pod2usage(-verbose => 2) if $manReq; if ($versionReq) { system('slxversion'); exit 1; } openslxInit(); my $openslxDB = OpenSLX::ConfigDB->new(); $openslxDB->connect(); my $action = shift @ARGV; if ($action =~ m[^add-system$]i) { addSystemToConfigDB(@ARGV); } elsif ($action =~ m[^add-client$]i) { addClientToConfigDB(@ARGV); } elsif ($action =~ m[^change-system$]i) { changeSystemInConfigDB(@ARGV); } elsif ($action =~ m[^change-client$]i) { changeClientInConfigDB(@ARGV); } elsif ($action =~ m[^list-c]) { print _tr("List of the matching clients:\n"); listClients(@ARGV); } elsif ($action =~ m[^list-e]) { print _tr("List of the matching exports:\n"); listExports(@ARGV); } elsif ($action =~ m[^list-s]) { print _tr("List of the matching systems:\n"); listSystems(@ARGV); } elsif ($action =~ m[^list-v]) { print _tr("List of the matching vendor-OSes:\n"); listVendorOSes(@ARGV); } elsif ($action =~ m[^remove-client$]i) { removeClientFromConfigDB(@ARGV); } elsif ($action =~ m[^remove-system$]i) { removeSystemFromConfigDB(@ARGV); } else { print STDERR _tr("You need to specify exactly one of these actions: add-client add-system change-client change-system list-client list-export list-system list-vendoros remove-client remove-system Try '%s --help' for more info.\n", $0); } $openslxDB->disconnect(); exit; sub parseKeyValueArgs { my $allowedKeys = shift; my $table = shift; my %dataHash; while (my $param = shift) { if ($param !~ m[^\s*(\w+)\s*=(.+)$]) { die _tr("value specification %s has unknown format, expected =\n", $param); } my $key = $1; my $value = $2; if (!grep { $_ eq $key } @$allowedKeys) { die _tr("unknown attribute '%s' specified for %s\n", $key, $table); } $dataHash{$1} = $2; } return \%dataHash; } sub dumpElements { my $objName = shift; if ($verbose) { foreach my $elem (@_) { print "$objName '$elem->{name}':\n"; print join( '', map { "\t$_" .substr(' ',length($_)) ." = $elem->{$_}\n"; } sort keys %$elem ); } } else { print join('', map { "\t$_->{name}\n" } @_); } } sub listClients { my @clientKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{client}}; my $clientData = parseKeyValueArgs(\@clientKeys, 'client', @_); dumpElements('client', sort { $a->{name} cmp $b->{name} } $openslxDB->fetchClientByFilter($clientData)); } sub listExports { my @exportKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{export}}; my $exportData = parseKeyValueArgs(\@exportKeys, 'export', @_); dumpElements('export', sort { $a->{name} cmp $b->{name} } $openslxDB->fetchExportByFilter($exportData)); } sub listSystems { my @systemKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{system}}; my $systemData = parseKeyValueArgs(\@systemKeys, 'system', @_); dumpElements('system', sort { $a->{name} cmp $b->{name} } $openslxDB->fetchSystemByFilter($systemData)); } sub listVendorOSes { my @vendorOSKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{vendor_os}}; my $vendorOSData = parseKeyValueArgs(\@vendorOSKeys, 'vendor_os', @_); dumpElements('vendor-OS', sort { $a->{name} cmp $b->{name} } $openslxDB->fetchVendorOSByFilter($vendorOSData)); } sub addClientToConfigDB { my @clientKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{client}}; push @clientKeys, 'systems'; my $clientData = parseKeyValueArgs(\@clientKeys, 'client', @_); my @systemIDs; my $systemNames; if (exists $clientData->{systems}) { @systemIDs = map { my $system = $openslxDB->fetchSystemByFilter({ 'name' => $_ }); if (!defined $system) { die _tr("system '%s' doesn't exist!\n", $_); } $system->{id}; } split ",", $clientData->{systems}; $systemNames = $clientData->{systems}; delete $clientData->{systems}; } if (!length($clientData->{name})) { die _tr("you have to specify the name for the new client\n"); } if (!length($clientData->{mac})) { die _tr("you have to specify the MAC for the new client\n"); } if ($clientData->{mac} !~ m[^(?:[[:xdigit:]][[:xdigit:]]:){5}?[[:xdigit:]][[:xdigit:]]$]) { die _tr("unknown MAC-format given, expected something like '01:02:03:04:05:06'!\n"); } if (!length($clientData->{boot_type})) { $clientData->{boot_type} = 'pxe'; } if ($openslxDB->fetchClientByFilter({ 'name' => $clientData->{name} })) { die _tr("the client '%s' already exists in the DB, giving up!\n", $clientData->{name}); } my $clientID = $openslxDB->addClient([$clientData]); vlog 0, _tr("client '%s' has been successfully added to DB (ID=%s)\n", $clientData->{name}, $clientID); if ($verbose) { listClient("name=$clientData->{name}"); } if (scalar(@systemIDs)) { $openslxDB->addSystemIDsToClient($clientID, \@systemIDs); if ($verbose) { print _tr("systems for this client are:\n\t%s\n", $systemNames); } } } sub addSystemToConfigDB { my @systemKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{system}}; push @systemKeys, 'clients', 'export'; my $systemData = parseKeyValueArgs(\@systemKeys, 'system', @_); if (!length($systemData->{export})) { die _tr("you have to specify the export the new system shall be using\n"); } my $exportName = $systemData->{export}; delete $systemData->{export}; my $export = $openslxDB->fetchExportByFilter({ 'name' => $exportName }); if (!defined $export) { die _tr("export '%s' could not be found in DB, giving up!\n", $exportName); } $systemData->{export_id} = $export->{id}; my @clientIDs; my $clientNames; if (exists $systemData->{clients}) { @clientIDs = map { my $client = $openslxDB->fetchClientByFilter({ 'name' => $_ }); if (!defined $client) { die _tr("client '%s' doesn't exist in DB, giving up!\n", $_); } $client->{id}; } split ",", $systemData->{clients}; $clientNames = $systemData->{clients}; delete $systemData->{clients}; } if (!length($systemData->{kernel})) { $systemData->{kernel} = 'vmlinuz'; } if (!length($systemData->{name})) { $systemData->{name} = "$exportName-$systemData->{kernel}"; } if (!length($systemData->{label})) { $systemData->{label} = "$exportName-$systemData->{kernel}"; } if (!length($systemData->{ramfs_debug_level})) { $systemData->{ramfs_debug_level} = '0'; } if (!length($systemData->{ramfs_use_glibc})) { $systemData->{ramfs_use_glibc} = '0'; } if (!length($systemData->{ramfs_use_busybox})) { $systemData->{ramfs_use_busybox} = '1'; } if ($openslxDB->fetchSystemByFilter({ 'name' => $systemData->{name} })) { die _tr("the system '%s' already exists in the DB, giving up!\n", $systemData->{name}); } my $systemID = $openslxDB->addSystem([$systemData]); vlog 0, _tr("system '%s' has been successfully added to DB (ID=%s)\n", $systemData->{name}, $systemID); if ($verbose) { listSystem("name=$systemData->{name}"); } if (scalar(@clientIDs)) { $openslxDB->addClientIDsToSystem($systemID, \@clientIDs); if ($verbose) { vlog 0, _tr("clients of this system are:\n\t%s\n", $clientNames); } } } sub changeClientInConfigDB { my @clientKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{client}}; push @clientKeys, 'systems'; my $clientData = parseKeyValueArgs(\@clientKeys, 'client', @_); if (!exists $clientData->{name}) { die _tr("you have to specify the name for the client you'd like to change!\n"); } my @systemIDs; my $systemNames; if (exists $clientData->{systems}) { @systemIDs = map { my $system = $openslxDB->fetchSystemByFilter({ 'name' => $_ }); if (!defined $system) { die _tr("system '%s' doesn't exist!\n", $_); } $system->{id}; } split ",", $clientData->{systems}; $systemNames = $clientData->{systems}; delete $clientData->{systems}; } my $client = $openslxDB->fetchClientByFilter({'name' => $clientData->{name}}); if (!defined $client) { die _tr("the client '%s' doesn't exists in the DB, giving up!\n", $clientData->{name}); } if ($clientData->{mac} !~ m[^(?:[[:xdigit:]][[:xdigit:]]:){5}?[[:xdigit:]][[:xdigit:]]$]) { die _tr("unknown MAC-format given, expected something like '01:02:03:04:05:06'!\n"); } $openslxDB->changeClient($client->{id}, [$clientData]); vlog 0, _tr("client '%s' has been successfully changed\n", $clientData->{name}); if ($verbose) { listClient("name=$clientData->{name}"); } if (scalar(@systemIDs)) { $openslxDB->setSystemIDsOfClient($client->{id}, \@systemIDs); if ($verbose) { print _tr("systems for this client are:\n\t%s\n", $systemNames); } } } sub changeSystemInConfigDB { my @systemKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{system}}; push @systemKeys, 'clients'; my $systemData = parseKeyValueArgs(\@systemKeys, 'system', @_); if (!exists $systemData->{name}) { die _tr("you have to specify the name of the system you'd like to change!\n"); } my @clientIDs; my $clientNames; if (exists $systemData->{clients}) { @clientIDs = map { my $client = $openslxDB->fetchClientByFilter({ 'name' => $_ }); if (!defined $client) { die _tr("client '%s' doesn't exist in DB, giving up!\n", $_); } $client->{id}; } split ",", $systemData->{clients}; $clientNames = $systemData->{clients}; delete $systemData->{clients}; } my $system = $openslxDB->fetchSystemByFilter({'name' => $systemData->{name}}); if (!defined $system) { die _tr("the system '%s' doesn't exists in the DB, giving up!\n", $systemData->{name}); } $openslxDB->changeSystem($system->{id}, [$systemData]); vlog 0, _tr("system '%s' has been successfully changed\n", $systemData->{name}); if ($verbose) { listSystems("name=$systemData->{name}"); } if (scalar(@clientIDs)) { $openslxDB->setClientIDsOfSystem($system->{id}, \@clientIDs); if ($verbose) { vlog 0, _tr("clients of this system are:\n\t%s\n", $clientNames); } } } sub removeClientFromConfigDB { my $clientData = parseKeyValueArgs(['name'], 'client', @_); if (!length($clientData->{name})) { die _tr("you have to specify the name of the client you'd like to remove!\n"); } my $client = $openslxDB->fetchClientByFilter({'name' => $clientData->{name}}); if (!defined $client) { die _tr("the client '%s' doesn't exists in the DB, giving up!\n", $clientData->{name}); } if ($client->{id} == 0) { die _tr("you can't remove the default-client!\n"); } $openslxDB->removeClient($client->{id}); vlog 0, _tr("client '%s' has been successfully removed from DB\n", $clientData->{name}); } sub removeSystemFromConfigDB { my $systemData = parseKeyValueArgs(['name'], 'system', @_); if (!length($systemData->{name})) { die _tr("you have to specify the name of the system you'd like to remove!\n"); } my $system = $openslxDB->fetchSystemByFilter({'name' => $systemData->{name}}); if (!defined $system) { die _tr("the system '%s' doesn't exists in the DB, giving up!\n", $systemData->{name}); } if ($system->{id} == 0) { die _tr("you can't remove the default-client!\n"); } $openslxDB->removeSystem($system->{id}); vlog 0, _tr("system '%s' has been successfully removed from DB\n", $systemData->{name}); } __END__ =head1 NAME slxconfig - OpenSLX-script to configure a vendor-OS for use with OpenSLX. You can create systems that will use the specified vendor-OS and you can create clients for that system, too. =head1 SYNOPSIS slxconfig [options] Options: --help brief help message --man show full documentation --verbose be more verbose --version show version Actions: add-client name= mac= ... add-system export= ... change-client name= [] ... change-system name= [] ... list-clients [] ... list-exports [] ... list-systems [] ... list-vendoroses [] ... remove-client name= remove-system name= =head1 OPTIONS =over 8 =item B<--help> Prints a brief help message and exits. =item B<--man> Prints the manual page and exits. =item B<--verbose> Prints more information during execution of any action. =item B<--version> Prints the version and exits. =back =head1 EXAMPLES =head2 Listing existing Clients / Exports / Systems / Vendor-OSes slxconfig list-client slxconfig list-export slxconfig list-system slxconfig list-vendoros lists all existing instances of the respective DB-objects. slxconfig list-client id=3 lists the client with id=3 slxconfig list-export type=nfs lists the client with id=3 =head2 Adding a new System to an exported Vendor-OS slxconfig add-system export-name= [clients=] [ ...] adds a new system to the config-DB. The new system will use the I whose name is given. If you specify clients (a comma-separated list of client names), the new system will be used by the given clients. =head2 Adding a new Client slxconfig add-client [systems= [ ...] adds a new client to the config-DB. If you specify systems (a comma-separated list of system names), the new client will use the given systems. =head2 Removing a System / Client slxconfig remove-system name= slxconfig remove-client name= removes the system/client with the given name. =cut