#! /usr/bin/perl # ----------------------------------------------------------------------------- # Copyright (c) 2006, 2007 - OpenSLX GmbH # # This program is free software distributed under the GPL version 2. # See http://openslx.org/COPYING # # If you have any feedback please consult http://openslx.org/feedback and # send your suggestions, praise, or complaints to feedback@openslx.org # # General information about OpenSLX can be found at http://openslx.org/ # ----------------------------------------------------------------------------- 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 { my $spc = ' 'x25; my $val = $elem->{$_}; $val =~ s[\n][\n\t$spc ]g; "\t$_" .substr($spc, length($_)) ." = $val\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', map { my @sysIDs = $openslxDB->aggregatedSystemIDsOfClient($_); $_->{systems} = join "\n", map { $_->{name} } sort { $a->{name} cmp $b->{name} } $openslxDB->fetchSystemByID(\@sysIDs, 'name'); $_; } 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', map { my $vendorOS = $openslxDB->fetchVendorOSByID($_->{vendor_os_id}, 'name'); if (defined $vendorOS) { $_->{vendor_os_id} .= " ($vendorOS->{name})"; } $_; } 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', map { my @clientIDs = $openslxDB->aggregatedClientIDsOfSystem($_); $_->{clients} = join "\n", map { $_->{name} } sort { $a->{name} cmp $b->{name} } $openslxDB->fetchClientByID(\@clientIDs, 'name'); my $export = $openslxDB->fetchExportByID($_->{export_id}, 'name'); if (defined $export) { $_->{export_id} .= " ($export->{name})"; } $_; } 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; 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 '\s*,\s*', $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 (defined @systemIDs) { $openslxDB->addSystemIDsToClient($clientID, \@systemIDs); } if ($verbose) { listClients("id=$clientID"); } } 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; 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 '\s*,\s*', $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 (defined @clientIDs) { $openslxDB->addClientIDsToSystem($systemID, \@clientIDs); } if ($verbose) { listSystems("id=$systemID"); } } sub changeClientInConfigDB { my @clientKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{client}}; push @clientKeys, 'systems', 'add-systems', 'remove-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 $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}); } my @systemIDs; 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}; delete $clientData->{systems}; } if (exists $clientData->{'add-systems'}) { @systemIDs = $openslxDB->fetchSystemIDsOfClient($client->{id}); push @systemIDs, map { my $system = $openslxDB->fetchSystemByFilter({ 'name' => $_ }); if (!defined $system) { die _tr("system '%s' doesn't exist!\n", $_); } $system->{id}; } split ",", $clientData->{'add-systems'}; delete $clientData->{'add-systems'}; } if (exists $clientData->{'remove-systems'}) { @systemIDs = $openslxDB->fetchSystemIDsOfClient($client->{id}); foreach my $sysName (split ",", $clientData->{'remove-systems'}) { my $system = $openslxDB->fetchSystemByFilter({ 'name' => $sysName }); if (!defined $system) { die _tr("system '%s' doesn't exist!\n", $sysName); } @systemIDs = grep { $_ != $system->{id} } @systemIDs; } delete $clientData->{'remove-systems'}; } if (length($clientData->{mac}) && $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 (defined @systemIDs) { $openslxDB->setSystemIDsOfClient($client->{id}, \@systemIDs); } if ($verbose) { listClients("id=$client->{id}"); } } sub changeSystemInConfigDB { my @systemKeys = map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{system}}; push @systemKeys, 'clients', 'add-clients', 'remove-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 $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}); } my @clientIDs; 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}; delete $systemData->{clients}; } if (exists $systemData->{'add-clients'}) { @clientIDs = $openslxDB->fetchClientIDsOfSystem($system->{id}); push @clientIDs, map { my $client = $openslxDB->fetchClientByFilter({ 'name' => $_ }); if (!defined $client) { die _tr("client '%s' doesn't exist!\n", $_); } $client->{id}; } split ",", $systemData->{'add-clients'}; delete $systemData->{'add-clients'}; } if (exists $systemData->{'remove-clients'}) { @clientIDs = $openslxDB->fetchClientIDsOfSystem($system->{id}); foreach my $clientName (split ",", $systemData->{'remove-clients'}) { my $client = $openslxDB->fetchClientByFilter({ 'name' => $clientName }); if (!defined $client) { die _tr("client '%s' doesn't exist!\n", $clientName); } @clientIDs = grep { $_ != $client->{id} } @clientIDs; } delete $systemData->{'remove-clients'}; } $openslxDB->changeSystem($system->{id}, [$systemData]); vlog 0, _tr("system '%s' has been successfully changed\n", $systemData->{name}); if (defined @clientIDs) { $openslxDB->setClientIDsOfSystem($system->{id}, \@clientIDs); } if ($verbose) { listSystems("id=$system->{id}"); } } 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 Changing a Client slxconfig change-client [add-systems=] [remove-systems=] [ ...] changes an existing client in the config-DB. With C you can add new systems to the specified client, and with C you can remove systems from it. Any other attributes specified on the commandline will directly change the data of the client itself. =head2 Changing a System slxconfig change-system [add-clients=] [remove-clients=] [ ...] changes an existing system in the config-DB. With C you can add new clients to the specified system, and with C you can remove clients from it. Any other attributes specified on the commandline will directly change the data of the system itself. =head2 Removing a System / Client slxconfig remove-system name= slxconfig remove-client name= removes the system/client with the given name. =cut