summaryrefslogblamecommitdiffstats
path: root/config-db/slxconfig
blob: e23552b3402867446b2facfc22adb9ac0cb4790b (plain) (tree)
1
2
3
4
5
6
7
8
9
                

                                                                               
 

                                                                    
 

                                                                         
 

                                                                               



                 


                                                                          














                                                                  
                      
                      



                 










                                                                       





                                                                                   






                             

                                         





                                       



















                                                         
        










                                                                           
                                       

 
                         









                               
                                                  












                                                                                          


                            
                                                           






                                                            


                                                                    
                                              

                                                                 




                                                
                                                          










                                                                   
                     
                                




                                                                                 
                                                                          





                                                                                      









                                                                   

                         


                                                                                            







                                                                                            
                                                                              

                                                            









                                                                   
                     
                                




                                                                                    
                                                                          









                                                                                          









                                                                          
                                        












                                                                                   









                                                                                            
                                                                  











                                                                                                    







                                                                                 
                                 
                                                                         


                                            


         




                                                   
                                              

                                                                   


                                                                     
                                             

                                                               
         





                                                                                           
         
                                                 

                      



                                            
                                                                                            
                                                       
                                                                                                     


                                              
                                                                  


                                              






                                                                                 
                                 
                                                                     


                                            


         
                          



                                                   
                                                                     

                                                                   


                                                                                               






                                                                                      
                      



                                            
                                                                                            





                                                                                    

                                              
























                                                                                            
         
 

                                                                                                  
                                                                                                    

         

                                                                  
                                                     
                                 
                                                                             


                                                


         




                                                   
                                                                     
                                                                   
 


                                                                                              
 





                                                                                      
                      










                                                                                                     

                                              
























                                                                                             
         


                                                                  
                                 
                                                                         


                                                

         
 


                                                               
 


                                                                                              
 











                                                                                      
 






                                                                                              
 











                                                                                      
 






                                                                     
 
               
 















































































                                                                       


              

























































































































                                                                               








                                      



                                                       





                             

               








                                                                 
 
                                                          
 
                                   
 
                          
 
                                       
 
                          
 
                                                   
 
                                             
 


                                                               
 

                                                                         
 



                                                                
 
                          
 
                                                                 
 


                                                               
 


                                                                              
 



                                                               
 

                                                               
 
                        
 
                                                                      
 

                                                              
 
                                                                    
 

                                                          
 
                                                                       
 

                                                       
 
                        
 
                                                               
 

                                                            
 
                                                                  
 

                                                            
 
                                                                     
 

                                                         
 
                                 
 
                                                       
 
                                                       
 
                                              
 
   
#! /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;
if ($manReq) {
	$ENV{LANG} = 'en_EN';
		# avoid dubious problem with perldoc in combination with UTF-8 that
		# leads to strange dashes and single-quotes being used
	pod2usage(-verbose => 2)
}
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 <key>=<value>\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;
	my $nameClause = shift || sub { "\t$_->{name}\n" };

	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('', sort map &$nameClause, @_);
	}
}

sub listClients
{
    my @clientKeys
		= map { (/^(\w+)\W/) ? $1 : $_; }
		  @{$DbSchema->{tables}->{client}};

    my $clientData = parseKeyValueArgs(\@clientKeys, 'client', @_);

	dumpElements(
		'client', undef,
		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',
		sub {
			"\t$_->{name}".substr(' ' x 30, length($_->{name}))."($_->{type})\n"
		},
		map {
			my $vendorOS
				= $openslxDB->fetchVendorOSByID($_->{vendor_os_id}, 'name');
			if (defined $vendorOS) {
				$_->{vendor_os_id} .= " ($vendorOS->{name})";
			}
			$_;
		}
		sort { $a->{name} eq $b->{name} || $a->{type} cmp $b->{type} }
		$openslxDB->fetchExportByFilter($exportData)
	);
}

sub listSystems
{
    my @systemKeys
		= map { (/^(\w+)\W/) ? $1 : $_; }
		  @{$DbSchema->{tables}->{system}};

    my $systemData = parseKeyValueArgs(\@systemKeys, 'system', @_);

	dumpElements(
		'system', undef,
		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', undef,
				 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 ($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->{name})) {
        die _tr("you have to specify the name of the new system!\n");
	}
	if (!length($systemData->{export})) {
		$systemData->{export} = $systemData->{name};
			# try falling back to given system name
	}
    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 ($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] <action> <key-value-pairs>

=head2 OpenSLX Options

    --base-path=<string>       basic path to project files
    --bin-path=<string>        path to binaries and scripts
    --config-path=<string>     path to configuration files
    --db-basepath=<string>     basic path to openslx database
    --db-datadir=<string>      data folder created under db-basepath
    --db-name=<string>         name of database
    --db-spec=<string>         full DBI-specification of database
    --db-type=<string>         type of database to connect to
    --export-path=<string>     path to root of all exported filesystems
    --locale=<string>          locale to use for translations
    --logfile=<string>         file to write logging output to
    --private-path=<string>    path to private data
    --public-path=<string>     path to public (client-accesible) data
    --share-path=<string>      path to sharable data
    --stage1-path=<string>     path to stage1 systems
    --temp-path=<string>       path to temporary data
    --tftpboot-path=<string>   path to root of tftp-server
    --verbose-level=<int>      level of logging verbosity (0-3)

=head2 General Options

    --help                     brief help message
    --man                      show full documentation
    --verbose                  be more verbose
    --version                  show version

=head2 Actions

=over 4

add-client name=<client-name> mac=<MAC> [<key>=<value> ...]

    adds a new client to the config-DB

add-system name=<system-name> [export=<export-name>] \
           [<key>=<value> ...]

    adds a new system to the config-DB

change-client name=<client-name> [<key>=<value> ...]

    changes the data of an existing system in the config-DB

change-system name=<system-name> [<key>=<value> ...]

    changes the data of an exiisting system in the config-DB

list-clients [<key>=<value> ...]

    lists all clients in config-DB (optionally matching given
    criteria)

list-exports [<key>=<value> ...]

    lists all exports in config-DB (optionally matching given
    criteria)

list-systems [<key>=<value> ...]

    lists all systems in config-DB (optionally matching given
    criteria)

list-vendoroses [<key>=<value> ...]

    lists all vendor-OSes in config-DB (optionally matching given
    criteria)

remove-client name=<client-name>

    removes a client from the config-DB

remove-system name=<system-name>

    removes a system from the config-DB

=back

=head1 OPTIONS

=head3 OpenSLX Options

=over 4

=item B<--base-path=<string>>

Sets basic path to project files.

Default is $SLX_BASE_PATH (usually F</opt/openslx>).

=item B<--bin-path=<string>>

Sets path to binaries and scripts.

Default is $SLX_BASE_PATH/bin (usually F</opt/openslx/bin>).

=item B<--config-path=<string>>

Sets path to configuration files.

Default is $SLX_CONFIG_PATH (usually F</etc/opt/openslx>).

=item B<--db-basepath=<string>>

Sets basic path to openslx database.

Default is $SLX_DB_PATH (usually F</var/opt/openslx/db>).

=item B<--db-datadir=<string>>

Sets data folder created under db-basepath.

Default is $SLX_DB_DATADIR (usually empty as it depends on db-type
whether or not such a directory is required at all).

=item B<--db-name=<string>>

Gives the name of the database to connect to.

Default is $SLX_DB_NAME (usually C<openslx>).

=item B<--db-spec=<string>>

Gives the full DBI-specification of database to connect to. Content depends
on the db-type.

Default is $SLX_DB_SPEC (usually empty as it will be built automatically).

=item B<--db-type=<string>>

Sets the type of database to connect to (CSV, SQLite, mysql, ...).

Default $SLX_DB_TYPE (usually C<CSV>).

=item B<--export-path=<string>>

Sets path to root of all exported filesystems. For each type of export (NFS,
NBD, ...) a separate folder will be created in here.

Default is $SLX_EXPORT_PATH (usually F</srv/openslx/export>.

=item B<--locale=<string>>

Sets the locale to use for translations.

Defaults to the system's standard locale.

=item B<--logfile=<string>>

Specifies a file where logging output will be written to.

Default is to log to STDERR.

=item B<--private-path=<string>>

Sets path to private data, where the config-db, vendor_oses and configurational
extensions will be stored.

Default is $SLX_PRIVATE_PATH (usually F</var/opt/openslx>.

=item B<--public-path=<string>>

Sets path to public (client-accesible) data.

Default is $SLX_PUBLIC_PATH (usually F</srv/openslx>.

=item B<--share-path=<string>>

Sets path to sharable data, where distro-specs and functionality templates
will be stored.

Default is $SLX_SHARE_PATH (usually F</opt/openslx/share>.

=item B<--stage1-path=<string>>

Sets path to stage1 systems, where distributor-systems will be installed.

Default is $SLX_STAGE1_PATH (usually F</var/opt/openslx/stage1>.

=item B<--temp-path=<string>>

Sets path to temporary data.

Default is $SLX_TEMP_PATH (usually F</tmp>.

=item B<--tftpboot-path=<string>>

Sets path to root of tftp-server from which clients will access their files.

Default is $SLX_TFTPBOOT_PATH (usually F</srv/openslx/tftpboot>.

=item B<--verbose-level=<int>>

Sets the level of logging verbosity (0-3).

Default is $SLX_VERBOSE_LEVEL (usually 0, no logging).

=back

=head3 General Options

=over 4

=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

=head3 Listing existing Clients / Exports / Systems / Vendor-OSes

=item B<slxconfig list-client>

=item B<slxconfig list-export>

=item B<slxconfig list-system>

=item B<slxconfig list-vendoros>

lists all existing instances of the respective DB-objects.

=item B<slxconfig list-client id=3>

lists the client with id=3

=item B<slxconfig list-export type=nfs>

lists the client with id=3

=head3 Adding a new System to an exported Vendor-OS

=item B<slxconfig add-system name=debian-4.0>

adds a new system named 'debian-4.0' to the config-DB that will
use the export of the same name. No client will be associated
with this system, yet.

=item B<slxconfig add-system name=suse-10.1 export-name=suse-10.1-kde \
                         clients=PC131,PC132,PC133 label="Linux Desktop">

adds a new system name 'suse-10.1' to the config-DB that will
use the export named 'suse-10.1-kde'. The system will be labeled
'Linux Desktop' and the clients 'PC131, 'PC132' and 'PC133' are
associated with this system (so they can boot it).

=head3 Adding a new Client

=item B<slxconfig add-client name=vmware-1 mac=01:02:03:04:05:06>

adds a new client named 'vmware-1', being identified by the MAC
'01:02:03:04:05:06' to the config-DB. No system will be
associated with this client, yet (so it can't boot anything).

=item B<slxconfig add-client name=vmware-1 mac=01:02:03:04:05:06
						systems=suse-10.1,debian-4.0 \
						attr_start_x=no>

adds a new client named 'vmware-1', being identified by the MAC
'01:02:03:04:05:06' to the config-DB. The systems 'suse-10.1' &
'Debian-4.0' will be associated with this client (so it will
offer these systems for booting).

During boot, the X-subsystem will not be started by this client
(so the systems will stay in console mode).

=head3 Changing a System

=item B<slxconfig change-system name=suse-10.1 attr_start_xdmcp=gnome>

will change the system named 'suse-10.1' such that it will use
the GNOME session manager.

=item B<slxconfig change-system name=suse-10.1 add-clients=vmware-1>

will associate the client 'vmware-1' with the system named
'suse-10.1'.

=item B<slxconfig change-system name=suse-10.1 remove-clients=vmware-1>

will remove the client 'vmware-1' from the system named
'suse-10.1'.

=head3 Changing a Client

=item B<slxconfig change-client name=PC131 attr_start_snmp=yes>

will change the client named 'PC131' such that it will start
the SNMP daemon on all systems that it boots.

=item B<slxconfig change-client name=PC131 add-systems=Debian-4.0>

will associate the system 'Debian-4.0' with the client named
'PC131'.

=item B<slxconfig change-client name=PC131 remove-systems=Debian-4.0>

will remove the system 'Debian-4.0' from the client named
'PC131'.

=head3 Removing a System / Client

=item B<< slxconfig remove-system name=<system-name> >>

=item B<< slxconfig remove-client name=<client-name> >>

removes the system/client with the given name.

=cut