From 175275655abd8a7a3db3c3a1dfc5ee49a6488307 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Mon, 7 Jan 2008 14:58:13 +0000 Subject: * finished refactoring of attribute handling code, especially the merging of attributes, such that all tests are passed * tested and finished implementation of group support in slxconfig * added new class AttributeRoster which keeps track of the known attributes (the ones provided by the openslx core and any other ones that may have been added by some plugin). * added new option --list-attributes to slxconfig which shows information about all known attributes git-svn-id: http://svn.openslx.org/svn/openslx/trunk@1444 95ad53e4-c205-0410-b2fa-d234c58c8868 --- config-db/OpenSLX/AttributeRoster.pm | 126 +++++++++ config-db/OpenSLX/ConfigDB.pm | 416 ++++++++++++----------------- config-db/OpenSLX/ConfigExport/DHCP/ISC.pm | 45 ++++ config-db/OpenSLX/DBSchema.pm | 394 ++++++++++++++++++++------- config-db/OpenSLX/Export/DHCP/ISC.pm | 45 ---- config-db/OpenSLX/MetaDB/DBI.pm | 381 +++++--------------------- config-db/slxconfig | 176 +++++++++--- config-db/slxconfig-demuxer | 55 ++-- config-db/t/12-system.t | 27 ++ config-db/t/13-client.t | 27 ++ config-db/t/14-group.t | 27 ++ config-db/t/25-attributes.t | 384 +++++++++++++------------- 12 files changed, 1135 insertions(+), 968 deletions(-) create mode 100644 config-db/OpenSLX/AttributeRoster.pm create mode 100644 config-db/OpenSLX/ConfigExport/DHCP/ISC.pm delete mode 100644 config-db/OpenSLX/Export/DHCP/ISC.pm (limited to 'config-db') diff --git a/config-db/OpenSLX/AttributeRoster.pm b/config-db/OpenSLX/AttributeRoster.pm new file mode 100644 index 00000000..46b90f74 --- /dev/null +++ b/config-db/OpenSLX/AttributeRoster.pm @@ -0,0 +1,126 @@ +# 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/ +# ----------------------------------------------------------------------------- +# AttributeRoster.pm +# - provides information about all available attributes +# ----------------------------------------------------------------------------- +package OpenSLX::AttributeRoster; + +use strict; +use warnings; + +our (@ISA, @EXPORT, $VERSION); + +use Exporter; +$VERSION = 0.2; +@ISA = qw(Exporter); + +@EXPORT = qw( + $%AttributeInfo +); + +use OpenSLX::Basics; + +################################################################################ +### +### Load the available AttrInfo-modules and build a hash containing info about +### all known attributes from the data contained in those modules. +### +################################################################################ + +my %AttributeInfo = (); + +my $libPath = "$openslxConfig{'base-path'}/lib"; +foreach my $module (glob("$libPath/OpenSLX/AttrInfo/*.pm")) { + next if $module !~ m{/([^/]+)\.pm$}; + my $class = "OpenSLX::AttrInfo::$1"; + vlog(2, "loading attr-info from module '$module'"); + my $instance = instantiateClass($class); + my $attrInfo = $instance->AttrInfo(); + foreach my $attr (keys %$attrInfo) { + $AttributeInfo{$attr} = $attrInfo->{$attr}; + } +} + +=item C + +Returns info about all attributes. + +=over + +=item Return Value + +An hash-ref with info about all known attributes. + +=back + +=cut + +sub getAttrInfo +{ + my $class = shift; + my $name = shift; + + if (defined $name) { + my $attrInfo = $AttributeInfo{$name}; + return if !defined $attrInfo; + return { $name => $AttributeInfo{$name} }; + } + + return \%AttributeInfo; +} + +=item C + +Returns the attribute names that apply to systems. + +=over + +=item Return Value + +An array of attribute names. + +=back + +=cut + +sub getSystemAttrs +{ + my $class = shift; + + return + grep { $AttributeInfo{$_}->{"applies_to_systems"} } + keys %AttributeInfo +} + +=item C + +Returns the attribute names that apply to clients. + +=over + +=item Return Value + +An array of attribute names. + +=back + +=cut + +sub getClientAttrs +{ + my $class = shift; + + return + grep { $AttributeInfo{$_}->{"applies_to_clients"} } + keys %AttributeInfo +} + +1; diff --git a/config-db/OpenSLX/ConfigDB.pm b/config-db/OpenSLX/ConfigDB.pm index 289f6f7f..8269ec0c 100644 --- a/config-db/OpenSLX/ConfigDB.pm +++ b/config-db/OpenSLX/ConfigDB.pm @@ -16,6 +16,8 @@ use warnings; our (@ISA, @EXPORT_OK, %EXPORT_TAGS, $VERSION); $VERSION = 1; # API-version +use Storable qw(dclone); + use Exporter; @ISA = qw(Exporter); @@ -81,7 +83,7 @@ to filtering (with boolean operators and hierarchical expressions)]. =cut my @supportExports = qw( - isAttribute mergeAttributes pushAttributes + mergeAttributes pushAttributes externalIDForSystem externalIDForClient externalConfigNameForClient externalAttrName generatePlaceholderFor ); @@ -112,6 +114,7 @@ sub new my $class = shift; my $self = { + 'db-schema' => OpenSLX::DBSchema->new, }; return bless $self, $class; @@ -182,7 +185,7 @@ sub connect ## no critic (ProhibitBuiltinHomonyms) $self->{'db-type'} = $dbType; $self->{'meta-db'} = $metaDB; - $self->_checkAndUpgradeDBSchemaIfNecessary($metaDB); + $self->{'db-schema'}->checkAndUpgradeDBSchemaIfNecessary($metaDB); return 1; } @@ -281,55 +284,7 @@ sub getColumnsOfTable my $self = shift; my $tableName = shift; - return - map { (/^(\w+)\W/) ? $1 : $_; } - @{$DbSchema->{tables}->{$tableName}->{cols}}; -} - -=item C - -Returns the attribute names that apply to systems. - -=over - -=item Return Value - -An array of attribute names. - -=back - -=cut - -sub getKnownSystemAttrs -{ - my $self = shift; - - return - grep { $AttributeInfo{$_}->{"applies_to_systems"} } - keys %AttributeInfo -} - -=item C - -Returns the attribute names that apply to clients. - -=over - -=item Return Value - -An array of attribute names. - -=back - -=cut - -sub getKnownClientAttrs -{ - my $self = shift; - - return - grep { $AttributeInfo{$_}->{"applies_to_clients"} } - keys %AttributeInfo + return $self->{'db-schema'}->getColumnsOfTable($tableName); } =item C @@ -1243,10 +1198,12 @@ The IDs of the new system(s), C if the creation failed. sub addSystem { - my $self = shift; - my $valRows = _aref(shift); + my $self = shift; + my $inValRows = _aref(shift); - _checkCols($valRows, 'system', qw(name export_id)); + _checkCols($inValRows, 'system', qw(name export_id)); + + my ($valRows, $attrValRows) = _cloneAndUnhingeAttrs($inValRows); foreach my $valRow (@$valRows) { if (!$valRow->{kernel}) { @@ -1264,7 +1221,7 @@ sub addSystem } } - return $self->{'meta-db'}->addSystem($valRows); + return $self->{'meta-db'}->addSystem($valRows, $attrValRows); } =item C @@ -1324,48 +1281,50 @@ sub changeSystem { my $self = shift; my $systemIDs = _aref(shift); - my $valRows = _aref(shift); + my $inValRows = _aref(shift); - return $self->{'meta-db'}->changeSystem($systemIDs, $valRows); -} + my ($valRows, $attrValRows) = _cloneAndUnhingeAttrs($inValRows); -=item C - -Sets a value for an attribute of the given system. If the system already -has a value for this attribute, it will be overwritten. - -=over - -=item Param C - -The ID of the system whose attribute shall be changed. - -=item Param C - -The name of the attribute to change. - -=item Param C - -The new value for the attribute. - -=item Return Value - -C<1> if the attribute could be set, C if not. - -=back - -=cut - -sub setSystemAttr -{ - my $self = shift; - my $systemID = shift; - my $attrName = shift; - my $attrValue = shift; - - return $self->{'meta-db'}->setSystemAttr($systemID, $attrName, $attrValue); + return $self->{'meta-db'}->changeSystem($systemIDs, $valRows, $attrValRows); } +#=item C +# +#Sets a value for an attribute of the given system. If the system already +#has a value for this attribute, it will be overwritten. +# +#=over +# +#=item Param C +# +#The ID of the system whose attribute shall be changed. +# +#=item Param C +# +#The name of the attribute to change. +# +#=item Param C +# +#The new value for the attribute. +# +#=item Return Value +# +#C<1> if the attribute could be set, C if not. +# +#=back +# +#=cut +# +#sub setSystemAttr +#{ +# my $self = shift; +# my $systemID = shift; +# my $attrName = shift; +# my $attrValue = shift; +# +# return $self->{'meta-db'}->setSystemAttr($systemID, $attrName, $attrValue); +#} + =item C Specifies all clients that should offer the given system for booting. @@ -1608,10 +1567,12 @@ The IDs of the new client(s), C if the creation failed. sub addClient { - my $self = shift; - my $valRows = _aref(shift); + my $self = shift; + my $inValRows = _aref(shift); + + _checkCols($inValRows, 'client', qw(name mac)); - _checkCols($valRows, 'client', qw(name mac)); + my ($valRows, $attrValRows) = _cloneAndUnhingeAttrs($inValRows); foreach my $valRow (@$valRows) { if (!$valRow->{boot_type}) { @@ -1619,7 +1580,7 @@ sub addClient } } - return $self->{'meta-db'}->addClient($valRows); + return $self->{'meta-db'}->addClient($valRows, $attrValRows); } =item C @@ -1679,48 +1640,50 @@ sub changeClient { my $self = shift; my $clientIDs = _aref(shift); - my $valRows = _aref(shift); - - return $self->{'meta-db'}->changeClient($clientIDs, $valRows); -} - -=item C - -Sets a value for an attribute of the given client. If the client already -has a value for this attribute, it will be overwritten. - -=over - -=item Param C - -The ID of the client whose attribute shall be changed. - -=item Param C - -The name of the attribute to change. - -=item Param C - -The new value for the attribute. - -=item Return Value - -C<1> if the attribute could be set, C if not. - -=back - -=cut + my $inValRows = _aref(shift); -sub setClientAttr -{ - my $self = shift; - my $clientID = shift; - my $attrName = shift; - my $attrValue = shift; + my ($valRows, $attrValRows) = _cloneAndUnhingeAttrs($inValRows); - return $self->{'meta-db'}->setClientAttr($clientID, $attrName, $attrValue); + return $self->{'meta-db'}->changeClient($clientIDs, $valRows, $attrValRows); } +#=item C +# +#Sets a value for an attribute of the given client. If the client already +#has a value for this attribute, it will be overwritten. +# +#=over +# +#=item Param C +# +#The ID of the client whose attribute shall be changed. +# +#=item Param C +# +#The name of the attribute to change. +# +#=item Param C +# +#The new value for the attribute. +# +#=item Return Value +# +#C<1> if the attribute could be set, C if not. +# +#=back +# +#=cut +# +#sub setClientAttr +#{ +# my $self = shift; +# my $clientID = shift; +# my $attrName = shift; +# my $attrValue = shift; +# +# return $self->{'meta-db'}->setClientAttr($clientID, $attrName, $attrValue); +#} + =item C Specifies all systems that should be offered for booting by the given client. @@ -1957,17 +1920,19 @@ The IDs of the new group(s), C if the creation failed. sub addGroup { - my $self = shift; - my $valRows = _aref(shift); + my $self = shift; + my $inValRows = _aref(shift); + + _checkCols($inValRows, 'group', qw(name)); - _checkCols($valRows, 'group', qw(name)); + my ($valRows, $attrValRows) = _cloneAndUnhingeAttrs($inValRows); foreach my $valRow (@$valRows) { if (!defined $valRow->{priority}) { $valRow->{priority} = '50'; } } - return $self->{'meta-db'}->addGroup($valRows); + return $self->{'meta-db'}->addGroup($valRows, $attrValRows); } =item C @@ -2001,42 +1966,42 @@ sub removeGroup return $self->{'meta-db'}->removeGroup($groupIDs); } -=item C - -Sets a value for an attribute of the given group. If the group already -has a value for this attribute, it will be overwritten. - -=over - -=item Param C - -The ID of the group whose attribute shall be changed. - -=item Param C - -The name of the attribute to change. - -=item Param C - -The new value for the attribute. - -=item Return Value - -C<1> if the attribute could be set, C if not. - -=back - -=cut - -sub setGroupAttr -{ - my $self = shift; - my $groupID = shift; - my $attrName = shift; - my $attrValue = shift; - - return $self->{'meta-db'}->setGroupAttr($groupID, $attrName, $attrValue); -} +#=item C +# +#Sets a value for an attribute of the given group. If the group already +#has a value for this attribute, it will be overwritten. +# +#=over +# +#=item Param C +# +#The ID of the group whose attribute shall be changed. +# +#=item Param C +# +#The name of the attribute to change. +# +#=item Param C +# +#The new value for the attribute. +# +#=item Return Value +# +#C<1> if the attribute could be set, C if not. +# +#=back +# +#=cut +# +#sub setGroupAttr +#{ +# my $self = shift; +# my $groupID = shift; +# my $attrName = shift; +# my $attrValue = shift; +# +# return $self->{'meta-db'}->setGroupAttr($groupID, $attrName, $attrValue); +#} =item C @@ -2062,11 +2027,13 @@ C<1> if the group(s) could be changed, C if not. sub changeGroup { - my $self = shift; - my $groupIDs = _aref(shift); - my $valRows = _aref(shift); + my $self = shift; + my $groupIDs = _aref(shift); + my $inValRows = _aref(shift); - return $self->{'meta-db'}->changeGroup($groupIDs, $valRows); + my ($valRows, $attrValRows) = _cloneAndUnhingeAttrs($inValRows); + + return $self->{'meta-db'}->changeGroup($groupIDs, $valRows, $attrValRows); } =item C @@ -2525,7 +2492,7 @@ sub aggregatedSystemFileInfoFor my $self = shift; my $system = shift; - my $info = {%$system}; + my $info = dclone($system); my $export = $self->fetchExportByID($system->{export_id}); if (!defined $export) { @@ -2586,32 +2553,6 @@ sub aggregatedSystemFileInfoFor =over -=item C - -Returns whether or not the given key is an exportable attribute. - -=over - -=item Param C - -The key to check. - -=item Return Value - -1 if the given key is indeed an attribute (currently, this means that -it starts with 'attr_'), 0 if not. - -=back - -=cut - -sub isAttribute -{ - my $key = shift; - - return $key =~ m[^attr_]; -} - =item C Copies all attributes from source that are unset in target over (source extends target). @@ -2648,7 +2589,7 @@ sub mergeAttributes my $sourceVal = $sourceAttrs->{$key}; my $targetVal = $targetAttrs->{$key}; if (defined $sourceVal && !defined $targetVal) { - vlog(0, _tr("merging %s (val=%s)", $key, $sourceVal)); + vlog(3, _tr("merging %s (val=%s)", $key, $sourceVal)); $targetAttrs->{$key} = $sourceVal; } } @@ -2851,51 +2792,6 @@ sub generatePlaceholderFor ################################################################################ ### private stuff ################################################################################ -sub _checkAndUpgradeDBSchemaIfNecessary -{ - my $self = shift; - my $metaDB = shift; - - vlog(2, "trying to determine schema version..."); - my $currVersion = $metaDB->schemaFetchDBVersion(); - if (!defined $currVersion) { - # that's bad, someone has messed with our DB: there is a - # database, but the 'meta'-table is empty. - # There might still be data in the other tables, but we have no way to - # find out which schema version they're in. So it's safer to give up. - croak _tr('Could not determine schema version of database'); - } - - if ($currVersion == 0) { - vlog(1, _tr('Creating DB (schema version: %s)', $DbSchema->{version})); - foreach my $tableName (keys %{$DbSchema->{tables}}) { - # create table (optionally inserting default values, too) - $metaDB->schemaAddTable( - $tableName, - $DbSchema->{tables}->{$tableName}->{cols}, - $DbSchema->{tables}->{$tableName}->{vals} - ); - } - $metaDB->schemaSetDBVersion($DbSchema->{version}); - vlog(1, _tr('DB has been created successfully')); - } elsif ($currVersion < $DbSchema->{version}) { - vlog( - 1, - _tr( - 'Our schema-version is %s, DB is %s, upgrading DB...', - $DbSchema->{version}, $currVersion - ) - ); - $metaDB->schemaUpgradeDBFrom($currVersion); - $metaDB->schemaSetDBVersion($DbSchema->{version}); - vlog(1, _tr('upgrade done')); - } else { - vlog(1, _tr('DB matches current schema version (%s)', $currVersion)); - } - - return 1; -} - sub _aref { # transparently converts the given reference to an array-ref my $ref = shift; @@ -2927,4 +2823,20 @@ sub _checkCols return 1; } +sub _cloneAndUnhingeAttrs +{ + my $inValRows = shift; + + # clone data and unhinge attrs + my (@valRows, @attrValRows); + foreach my $inValRow (@$inValRows) { + push @attrValRows, $inValRow->{attrs}; + my $valRow = dclone($inValRow); + delete $valRow->{attrs}; + push @valRows, $valRow; + } + + return (\@valRows, \@attrValRows); +} + 1; diff --git a/config-db/OpenSLX/ConfigExport/DHCP/ISC.pm b/config-db/OpenSLX/ConfigExport/DHCP/ISC.pm new file mode 100644 index 00000000..e3dd0738 --- /dev/null +++ b/config-db/OpenSLX/ConfigExport/DHCP/ISC.pm @@ -0,0 +1,45 @@ +# 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/ +# ----------------------------------------------------------------------------- +# ISC.pm +# - provides ISC-specific implementation of DHCP export. +# ----------------------------------------------------------------------------- +package OpenSLX::ConfigExport::DHCP::ISC; + +use strict; +use warnings; + +our $VERSION = 1.01; # API-version . implementation-version + +################################################################################ +### This class provides an ISC specific implementation for DHCP export. +################################################################################ +use OpenSLX::Basics; + +################################################################################ +### implementation +################################################################################ +sub new +{ + my $class = shift; + my $self = {}; + return bless $self, $class; +} + +sub execute +{ + my $self = shift; + my $clients = shift; + + vlog(1, _tr("writing dhcp-config for %s clients", scalar(@$clients))); + foreach my $client (@$clients) { +print "ISC-DHCP: $client->{name}\n"; + } +} \ No newline at end of file diff --git a/config-db/OpenSLX/DBSchema.pm b/config-db/OpenSLX/DBSchema.pm index 801f50a9..cd92c07e 100644 --- a/config-db/OpenSLX/DBSchema.pm +++ b/config-db/OpenSLX/DBSchema.pm @@ -16,25 +16,8 @@ package OpenSLX::DBSchema; use strict; use warnings; -our (@ISA, @EXPORT, $VERSION); - -use Exporter; -$VERSION = 0.2; -@ISA = qw(Exporter); - -@EXPORT = qw( - $DbSchema %DbSchemaHistory %AttributeInfo -); - -our ($DbSchema, %DbSchemaHistory, %AttributeInfo); - - use OpenSLX::Basics; -use POSIX qw(locale_h); -my $lang = setlocale(LC_MESSAGES); -my $country = $lang =~ m[^\w\w_(\w\w)] ? lc($1) : 'us'; - ################################################################################ ### DB-schema definition ### This hash-ref describes the current OpenSLX configuration database @@ -51,7 +34,13 @@ my $country = $lang =~ m[^\w\w_(\w\w)] ? lc($1) : 'us'; ### fk => foreign key (integer) ################################################################################ -$DbSchema = { +use POSIX qw(locale_h); +my $lang = setlocale(LC_MESSAGES); +my $country = $lang =~ m[^\w\w_(\w\w)] ? lc($1) : 'us'; + +my $VERSION = 0.2; + +my $DbSchema = { 'version' => $VERSION, 'tables' => { 'client' => { @@ -170,7 +159,7 @@ $DbSchema = { ], 'vals' => [ { - 'schema_version' => $DbSchema->{'version'}, + 'schema_version' => $VERSION, }, ], }, @@ -211,16 +200,6 @@ $DbSchema = { ], 'vals' => [ # attributes of default system - { - 'system_id' => 0, - 'name' => 'automnt_dir', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'automnt_src', - 'value' => '', - }, { 'system_id' => 0, 'name' => 'country', @@ -231,21 +210,6 @@ $DbSchema = { 'name' => 'dm_allow_shutdown', 'value' => 'user', }, - { - 'system_id' => 0, - 'name' => 'hw_graphic', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'hw_monitor', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'hw_mouse', - 'value' => '', - }, { 'system_id' => 0, 'name' => 'late_dm', @@ -256,52 +220,12 @@ $DbSchema = { 'name' => 'netbios_workgroup', 'value' => 'slx-network', }, - { - 'system_id' => 0, - 'name' => 'nis_domain', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'nis_servers', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'ramfs_fsmods', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'ramfs_miscmods', - 'value' => '', - }, { 'system_id' => 0, 'name' => 'ramfs_nicmods', 'value' => 'forcedeth e1000 e100 tg3 via-rhine r8169 pcnet32', }, - { - 'system_id' => 0, - 'name' => 'ramfs_screen', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'sane_scanner', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'scratch', - 'value' => '', - }, - { - 'system_id' => 0, - 'name' => 'slxgrp', - 'value' => '', - }, { 'system_id' => 0, 'name' => 'start_alsasound', @@ -409,23 +333,301 @@ $DbSchema = { ################################################################################ ### -### Load the available AttrInfo-modules and build a hash containing info about -### all known attributes from the data contained in those modules. +### standard methods +### +################################################################################ +sub new +{ + my $class = shift; + + my $self = { + }; + + return bless $self, $class; +} + +sub checkAndUpgradeDBSchemaIfNecessary +{ + my $self = shift; + my $metaDB = shift; + + vlog(2, "trying to determine schema version..."); + my $currVersion = $metaDB->schemaFetchDBVersion(); + if (!defined $currVersion) { + # that's bad, someone has messed with our DB: there is a + # database, but the 'meta'-table is empty. + # There might still be data in the other tables, but we have no way to + # find out which schema version they're in. So it's safer to give up. + croak _tr('Could not determine schema version of database'); + } + + if ($currVersion == 0) { + vlog(1, _tr('Creating DB (schema version: %s)', $DbSchema->{version})); + foreach my $tableName (keys %{$DbSchema->{tables}}) { + # create table (optionally inserting default values, too) + $metaDB->schemaAddTable( + $tableName, + $DbSchema->{tables}->{$tableName}->{cols}, + $DbSchema->{tables}->{$tableName}->{vals} + ); + } + $metaDB->schemaSetDBVersion($DbSchema->{version}); + vlog(1, _tr('DB has been created successfully')); + } elsif ($currVersion < $DbSchema->{version}) { + vlog( + 1, + _tr( + 'Our schema-version is %s, DB is %s, upgrading DB...', + $DbSchema->{version}, $currVersion + ) + ); + $self->_schemaUpgradeDBFrom($metaDB, $currVersion); + $metaDB->schemaSetDBVersion($DbSchema->{version}); + vlog(1, _tr('upgrade done')); + } else { + vlog(1, _tr('DB matches current schema version (%s)', $currVersion)); + } + + return 1; +} + +sub getColumnsOfTable +{ + my $self = shift; + my $tableName = shift; + + return + map { (/^(\w+)\W/) ? $1 : $_; } + @{$DbSchema->{tables}->{$tableName}->{cols}}; +} + +################################################################################ +### +### methods for upgrading the DB schema ### ################################################################################ +sub _schemaUpgradeDBFrom +{ + my $self = shift; + my $metaDB = shift; + my $currVersion = shift; -%AttributeInfo = (); + $self->_upgradeDBTo0_2($metaDB) if $currVersion < 0.2; + + return 1; +} -my $libPath = "$openslxConfig{'base-path'}/lib"; -foreach my $module (glob("$libPath/OpenSLX/AttrInfo/*.pm")) { - next if $module !~ m{/([^/]+)\.pm$}; - my $class = "OpenSLX::AttrInfo::$1"; - vlog(2, "loading attr-info from module '$module'"); - my $instance = instantiateClass($class); - my $attrInfo = $instance->AttrInfo(); - foreach my $attr (keys %$attrInfo) { - $AttributeInfo{$attr} = $attrInfo->{$attr}; +sub _upgradeDBTo0_2 +{ + my $self = shift; + my $metaDB = shift; + + # move attributes into separate tables ... + # + # ... system attributes ... + $metaDB->schemaAddTable( + 'system_attr', + [ + 'id:pk', + 'system_id:fk', + 'name:s.128', + 'value:s.255', + ] + ); + foreach my $system ($metaDB->fetchSystemByFilter()) { + my %attrs; + foreach my $key (keys %$system) { + next if substr($key, 0, 5) ne 'attr_'; + my $attrValue = $system->{$key} || ''; + next if $system->{id} > 0 && !length($attrValue); + my $newAttrName = substr($key, 5); + $attrs{$newAttrName} = $attrValue; + } + $metaDB->setSystemAttrs($system->{id}, \%attrs); + } + $metaDB->schemaDropColumns( + 'system', + [ + 'attr_automnt_dir', + 'attr_automnt_src', + 'attr_country', + 'attr_dm_allow_shutdown', + 'attr_hw_graphic', + 'attr_hw_monitor', + 'attr_hw_mouse', + 'attr_late_dm', + 'attr_netbios_workgroup', + 'attr_nis_domain', + 'attr_nis_servers', + 'attr_ramfs_fsmods', + 'attr_ramfs_miscmods', + 'attr_ramfs_nicmods', + 'attr_ramfs_screen', + 'attr_sane_scanner', + 'attr_scratch', + 'attr_slxgrp', + 'attr_start_alsasound', + 'attr_start_atd', + 'attr_start_cron', + 'attr_start_dreshal', + 'attr_start_ntp', + 'attr_start_nfsv4', + 'attr_start_printer', + 'attr_start_samba', + 'attr_start_snmp', + 'attr_start_sshd', + 'attr_start_syslog', + 'attr_start_x', + 'attr_start_xdmcp', + 'attr_tex_enable', + 'attr_timezone', + 'attr_tvout', + 'attr_vmware', + ], + [ + 'id:pk', + 'export_id:fk', + 'name:s.64', + 'label:s.64', + 'kernel:s.128', + 'kernel_params:s.512', + 'hidden:b', + 'comment:s.1024', + ] + ); + # + # ... client attributes ... + $metaDB->schemaAddTable( + 'client_attr', + [ + 'id:pk', + 'client_id:fk', + 'name:s.128', + 'value:s.255', + ] + ); + foreach my $client ($metaDB->fetchClientByFilter()) { + my %attrs; + foreach my $key (keys %$client) { + next if substr($key, 0, 5) ne 'attr_'; + my $attrValue = $client->{$key} || ''; + next if !length($attrValue); + my $newAttrName = substr($key, 5); + $attrs{$newAttrName} = $attrValue; + } + $metaDB->setClientAttrs($client->{id}, \%attrs); } + $metaDB->schemaDropColumns( + 'client', + [ + 'attr_automnt_dir', + 'attr_automnt_src', + 'attr_country', + 'attr_dm_allow_shutdown', + 'attr_hw_graphic', + 'attr_hw_monitor', + 'attr_hw_mouse', + 'attr_late_dm', + 'attr_netbios_workgroup', + 'attr_nis_domain', + 'attr_nis_servers', + 'attr_sane_scanner', + 'attr_scratch', + 'attr_slxgrp', + 'attr_start_alsasound', + 'attr_start_atd', + 'attr_start_cron', + 'attr_start_dreshal', + 'attr_start_ntp', + 'attr_start_nfsv4', + 'attr_start_printer', + 'attr_start_samba', + 'attr_start_snmp', + 'attr_start_sshd', + 'attr_start_syslog', + 'attr_start_x', + 'attr_start_xdmcp', + 'attr_tex_enable', + 'attr_timezone', + 'attr_tvout', + 'attr_vmware', + ], + [ + 'id:pk', + 'name:s.128', + 'mac:s.20', + 'boot_type:s.20', + 'unbootable:b', + 'kernel_params:s.128', + 'comment:s.1024', + ] + ); + # + # ... group attributes ... + $metaDB->schemaAddTable( + 'group_attr', + [ + 'id:pk', + 'group_id:fk', + 'name:s.128', + 'value:s.255', + ] + ); + foreach my $group ($metaDB->fetchGroupByFilter()) { + my %attrs; + foreach my $key (keys %$group) { + next if substr($key, 0, 5) ne 'attr_'; + my $attrValue = $group->{$key} || ''; + next if !length($attrValue); + my $newAttrName = substr($key, 5); + $attrs{$newAttrName} = $attrValue; + } + $metaDB->setGroupAttrs($group->{id}, \%attrs); + } + $metaDB->schemaDropColumns( + 'groups', + [ + 'attr_automnt_dir', + 'attr_automnt_src', + 'attr_country', + 'attr_dm_allow_shutdown', + 'attr_hw_graphic', + 'attr_hw_monitor', + 'attr_hw_mouse', + 'attr_late_dm', + 'attr_netbios_workgroup', + 'attr_nis_domain', + 'attr_nis_servers', + 'attr_sane_scanner', + 'attr_scratch', + 'attr_slxgrp', + 'attr_start_alsasound', + 'attr_start_atd', + 'attr_start_cron', + 'attr_start_dreshal', + 'attr_start_ntp', + 'attr_start_nfsv4', + 'attr_start_printer', + 'attr_start_samba', + 'attr_start_snmp', + 'attr_start_sshd', + 'attr_start_syslog', + 'attr_start_x', + 'attr_start_xdmcp', + 'attr_tex_enable', + 'attr_timezone', + 'attr_tvout', + 'attr_vmware', + ], + [ + 'id:pk', + 'name:s.128', + 'priority:i', + 'comment:s.1024', + ] + ); + + return 1; } 1; diff --git a/config-db/OpenSLX/Export/DHCP/ISC.pm b/config-db/OpenSLX/Export/DHCP/ISC.pm deleted file mode 100644 index 2e7aa01b..00000000 --- a/config-db/OpenSLX/Export/DHCP/ISC.pm +++ /dev/null @@ -1,45 +0,0 @@ -# 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/ -# ----------------------------------------------------------------------------- -# ISC.pm -# - provides ISC-specific implementation of DHCP export. -# ----------------------------------------------------------------------------- -package OpenSLX::Export::DHCP::ISC; - -use strict; -use warnings; - -our $VERSION = 1.01; # API-version . implementation-version - -################################################################################ -### This class provides an ISC specific implementation for DHCP export. -################################################################################ -use OpenSLX::Basics; - -################################################################################ -### implementation -################################################################################ -sub new -{ - my $class = shift; - my $self = {}; - return bless $self, $class; -} - -sub execute -{ - my $self = shift; - my $clients = shift; - - vlog(1, _tr("writing dhcp-config for %s clients", scalar(@$clients))); - foreach my $client (@$clients) { -print "ISC-DHCP: $client->{name}\n"; - } -} \ No newline at end of file diff --git a/config-db/OpenSLX/MetaDB/DBI.pm b/config-db/OpenSLX/MetaDB/DBI.pm index 98754777..a6d2eef0 100644 --- a/config-db/OpenSLX/MetaDB/DBI.pm +++ b/config-db/OpenSLX/MetaDB/DBI.pm @@ -713,24 +713,16 @@ sub changeGlobalInfo sub addSystem { - my $self = shift; - my $valRows = shift; - - # separate the attribute hashes ... - my @attrValRows - = map { - my $attrs = $_->{attrs}; - delete $_->{attrs}; - $attrs; - } - @$valRows; + my $self = shift; + my $valRows = shift; + my $attrValRows = shift; # ... store the systems to get the IDs ... my @systemIDs = $self->_doInsert('system', $valRows); # ... finally store the individual attribute sets foreach my $id (@systemIDs) { - my $attrs = shift @attrValRows; + my $attrs = shift @$attrValRows; next if !defined $attrs; return if !$self->setSystemAttrs($id, $attrs); } @@ -751,17 +743,11 @@ sub changeSystem my $self = shift; my $systemIDs = shift; my $valRows = shift; + my $attrValRows = shift; - # separate the attribute hashes and store them individually - my @attrValRows - = map { - my $attrs = $_->{attrs}; - delete $_->{attrs}; - $attrs; - } - @$valRows; + # store the attribute hashes individually foreach my $id (@$systemIDs) { - my $attrs = shift @attrValRows; + my $attrs = shift @$attrValRows; next if !defined $attrs; return if !$self->setSystemAttrs($id, $attrs); } @@ -776,20 +762,21 @@ sub setSystemAttrs my $systemID = shift; my $attrs = shift; - # we take the simple path and remove all attributes ... + # for now we take the simple path and remove all attributes ... return if !$self->_doDelete('system_attr', [ $systemID ], 'system_id'); # ... and (re-)insert the given ones - foreach my $key (keys %$attrs) { - return if !$self->_doInsert( - 'system_attr', [ { - system_id => $systemID, - name => $key, - value => $attrs->{$key}, - } ] - ); - } - return 1; + my @attrData + = map { + { + system_id => $systemID, + name => $_, + value => $attrs->{$_}, + } + } + grep { defined $attrs->{$_} } + keys %$attrs; + return $self->_doInsert('system_attr', [ @attrData ]); } sub setClientIDsOfSystem @@ -822,22 +809,14 @@ sub addClient { my $self = shift; my $valRows = shift; - - # separate the attribute hashes ... - my @attrValRows - = map { - my $attrs = $_->{attrs}; - delete $_->{attrs}; - $attrs; - } - @$valRows; + my $attrValRows = shift; # ... store the clients to get the IDs ... my @clientIDs = $self->_doInsert('client', $valRows); # ... finally store the individual attribute sets foreach my $id (@clientIDs) { - my $attrs = shift @attrValRows; + my $attrs = shift @$attrValRows; next if !defined $attrs; return if !$self->setClientAttrs($id, $attrs); } @@ -855,20 +834,14 @@ sub removeClient sub changeClient { - my $self = shift; - my $clientIDs = shift; - my $valRows = shift; + my $self = shift; + my $clientIDs = shift; + my $valRows = shift; + my $attrValRows = shift; - # separate the attribute hashes and store them individually - my @attrValRows - = map { - my $attrs = $_->{attrs}; - delete $_->{attrs}; - $attrs; - } - @$valRows; + # store the attribute hashes individually foreach my $id (@$clientIDs) { - my $attrs = shift @attrValRows; + my $attrs = shift @$attrValRows; next if !defined $attrs; return if !$self->setClientAttrs($id, $attrs); } @@ -883,19 +856,21 @@ sub setClientAttrs my $clientID = shift; my $attrs = shift; - # we take the simple path and remove all attributes ... + # for now we take the simple path and remove all attributes ... return if !$self->_doDelete('client_attr', [ $clientID ], 'client_id'); # ... and (re-)insert the given ones - foreach my $key (keys %$attrs) { - return if !$self->_doInsert( - 'client_attr', [ { - client_id => $clientID, - name => $key, - value => $attrs->{$key}, - } ] - ); - } + my @attrData + = map { + { + client_id => $clientID, + name => $_, + value => $attrs->{$_}, + } + } + grep { defined $attrs->{$_} } + keys %$attrs; + return $self->_doInsert('client_attr', [ @attrData ]); return 1; } @@ -927,24 +902,16 @@ sub setGroupIDsOfClient sub addGroup { - my $self = shift; - my $valRows = shift; - - # separate the attribute hashes ... - my @attrValRows - = map { - my $attrs = $_->{attrs}; - delete $_->{attrs}; - $attrs; - } - @$valRows; + my $self = shift; + my $valRows = shift; + my $attrValRows = shift; # ... store the groups to get the IDs ... my @groupIDs = $self->_doInsert('groups', $valRows); # ... finally store the individual attribute sets foreach my $id (@groupIDs) { - my $attrs = shift @attrValRows; + my $attrs = shift @$attrValRows; next if !defined $attrs; return if !$self->setGroupAttrs($id, $attrs); } @@ -962,20 +929,14 @@ sub removeGroup sub changeGroup { - my $self = shift; - my $groupIDs = shift; - my $valRows = shift; + my $self = shift; + my $groupIDs = shift; + my $valRows = shift; + my $attrValRows = shift; - # separate the attribute hashes and store them individually - my @attrValRows - = map { - my $attrs = $_->{attrs}; - delete $_->{attrs}; - $attrs; - } - @$valRows; + # store the attribute hashes individually foreach my $id (@$groupIDs) { - my $attrs = shift @attrValRows; + my $attrs = shift @$attrValRows; next if !defined $attrs; return if !$self->setGroupAttrs($id, $attrs); } @@ -990,19 +951,21 @@ sub setGroupAttrs my $groupID = shift; my $attrs = shift; - # we take the simple path and remove all attributes ... + # for now we take the simple path and remove all attributes ... return if !$self->_doDelete('group_attr', [ $groupID ], 'group_id'); # ... and (re-)insert the given ones - foreach my $key (keys %$attrs) { - return if !$self->_doInsert( - 'group_attr', [ { - group_id => $groupID, - name => $key, - value => $attrs->{$key}, - } ] - ); - } + my @attrData + = map { + { + group_id => $groupID, + name => $_, + value => $attrs->{$_}, + } + } + grep { defined $attrs->{$_} } + keys %$attrs; + return $self->_doInsert('group_attr', [ @attrData ]); return 1; } @@ -1089,16 +1052,6 @@ sub schemaFetchDBVersion return $row->{schema_version}; } -sub schemaUpgradeDBFrom -{ - my $self = shift; - my $currVersion = shift; - - $self->_upgradeDBTo0_2() if $currVersion < 0.2; - - return 1; -} - sub schemaSetDBVersion { my $self = shift; @@ -1317,218 +1270,6 @@ sub schemaChangeColumns return; } -sub _upgradeDBTo0_2 -{ - my $self = shift; - - # move attributes into separate tables ... - # - # ... system attributes ... - $self->schemaAddTable( - 'system_attr', - [ - 'id:pk', - 'system_id:fk', - 'name:s.128', - 'value:s.255', - ] - ); - foreach my $system ($self->fetchSystemByFilter()) { - my %attrs; - foreach my $key (keys %$system) { - next if substr($key, 0, 5) ne 'attr_'; - my $attrValue = $system->{$key} || ''; - next if $system->{id} > 0 && !length($attrValue); - my $newAttrName = substr($key, 5); - $attrs{$newAttrName} = $attrValue; - } - $self->setSystemAttrs($system->{id}, \%attrs); - } - $self->schemaDropColumns( - 'system', - [ - 'attr_automnt_dir', - 'attr_automnt_src', - 'attr_country', - 'attr_dm_allow_shutdown', - 'attr_hw_graphic', - 'attr_hw_monitor', - 'attr_hw_mouse', - 'attr_late_dm', - 'attr_netbios_workgroup', - 'attr_nis_domain', - 'attr_nis_servers', - 'attr_ramfs_fsmods', - 'attr_ramfs_miscmods', - 'attr_ramfs_nicmods', - 'attr_ramfs_screen', - 'attr_sane_scanner', - 'attr_scratch', - 'attr_slxgrp', - 'attr_start_alsasound', - 'attr_start_atd', - 'attr_start_cron', - 'attr_start_dreshal', - 'attr_start_ntp', - 'attr_start_nfsv4', - 'attr_start_printer', - 'attr_start_samba', - 'attr_start_snmp', - 'attr_start_sshd', - 'attr_start_syslog', - 'attr_start_x', - 'attr_start_xdmcp', - 'attr_tex_enable', - 'attr_timezone', - 'attr_tvout', - 'attr_vmware', - ], - [ - 'id:pk', - 'export_id:fk', - 'name:s.64', - 'label:s.64', - 'kernel:s.128', - 'kernel_params:s.512', - 'hidden:b', - 'comment:s.1024', - ] - ); - # - # ... client attributes ... - $self->schemaAddTable( - 'client_attr', - [ - 'id:pk', - 'client_id:fk', - 'name:s.128', - 'value:s.255', - ] - ); - foreach my $client ($self->fetchClientByFilter()) { - my %attrs; - foreach my $key (keys %$client) { - next if substr($key, 0, 5) ne 'attr_'; - my $attrValue = $client->{$key} || ''; - next if !length($attrValue); - my $newAttrName = substr($key, 5); - $attrs{$newAttrName} = $attrValue; - } - $self->setClientAttrs($client->{id}, \%attrs); - } - $self->schemaDropColumns( - 'client', - [ - 'attr_automnt_dir', - 'attr_automnt_src', - 'attr_country', - 'attr_dm_allow_shutdown', - 'attr_hw_graphic', - 'attr_hw_monitor', - 'attr_hw_mouse', - 'attr_late_dm', - 'attr_netbios_workgroup', - 'attr_nis_domain', - 'attr_nis_servers', - 'attr_sane_scanner', - 'attr_scratch', - 'attr_slxgrp', - 'attr_start_alsasound', - 'attr_start_atd', - 'attr_start_cron', - 'attr_start_dreshal', - 'attr_start_ntp', - 'attr_start_nfsv4', - 'attr_start_printer', - 'attr_start_samba', - 'attr_start_snmp', - 'attr_start_sshd', - 'attr_start_syslog', - 'attr_start_x', - 'attr_start_xdmcp', - 'attr_tex_enable', - 'attr_timezone', - 'attr_tvout', - 'attr_vmware', - ], - [ - 'id:pk', - 'name:s.128', - 'mac:s.20', - 'boot_type:s.20', - 'unbootable:b', - 'kernel_params:s.128', - 'comment:s.1024', - ] - ); - # - # ... group attributes ... - $self->schemaAddTable( - 'group_attr', - [ - 'id:pk', - 'group_id:fk', - 'name:s.128', - 'value:s.255', - ] - ); - foreach my $group ($self->fetchGroupByFilter()) { - my %attrs; - foreach my $key (keys %$group) { - next if substr($key, 0, 5) ne 'attr_'; - my $attrValue = $group->{$key} || ''; - next if !length($attrValue); - my $newAttrName = substr($key, 5); - $attrs{$newAttrName} = $attrValue; - } - $self->setGroupAttrs($group->{id}, \%attrs); - } - $self->schemaDropColumns( - 'groups', - [ - 'attr_automnt_dir', - 'attr_automnt_src', - 'attr_country', - 'attr_dm_allow_shutdown', - 'attr_hw_graphic', - 'attr_hw_monitor', - 'attr_hw_mouse', - 'attr_late_dm', - 'attr_netbios_workgroup', - 'attr_nis_domain', - 'attr_nis_servers', - 'attr_sane_scanner', - 'attr_scratch', - 'attr_slxgrp', - 'attr_start_alsasound', - 'attr_start_atd', - 'attr_start_cron', - 'attr_start_dreshal', - 'attr_start_ntp', - 'attr_start_nfsv4', - 'attr_start_printer', - 'attr_start_samba', - 'attr_start_snmp', - 'attr_start_sshd', - 'attr_start_syslog', - 'attr_start_x', - 'attr_start_xdmcp', - 'attr_tex_enable', - 'attr_timezone', - 'attr_tvout', - 'attr_vmware', - ], - [ - 'id:pk', - 'name:s.128', - 'priority:i', - 'comment:s.1024', - ] - ); - - return 1; -} - 1; =head1 NAME diff --git a/config-db/slxconfig b/config-db/slxconfig index 6df489ca..ce2a203c 100755 --- a/config-db/slxconfig +++ b/config-db/slxconfig @@ -23,6 +23,7 @@ slxconfig use Getopt::Long qw(:config pass_through); use List::Util qw(max); use Pod::Usage; +use Storable qw(dclone); # add the folder this script lives in and the lib-folder to perl's # search path for modules: @@ -34,6 +35,7 @@ use lib "$FindBin::RealBin/../config-db"; # development path to config-db +use OpenSLX::AttributeRoster; use OpenSLX::Basics; use OpenSLX::ConfigDB; use OpenSLX::ConfigFolder; @@ -49,10 +51,9 @@ GetOptions( ) 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 + $ENV{LC_MESSAGES} = 'POSIX'; pod2usage(-verbose => 2); } if ($versionReq) { @@ -90,6 +91,10 @@ elsif ($action =~ m[^change-s]i) { elsif ($action =~ m[^change-c]i) { changeClientInConfigDB(@ARGV); } +elsif ($action =~ m[^list-a]) { + print _tr("List of known attributes:\n"); + listAttributes(@ARGV); +} elsif ($action =~ m[^list-c]) { print _tr("List of clients:\n"); listClients(@ARGV); @@ -134,7 +139,7 @@ elsif ($action =~ m[^remove-c]i) { removeClientFromConfigDB(@ARGV); } elsif ($action =~ m[^remove-g]i) { - removeClientFromConfigDB(@ARGV); + removeGroupFromConfigDB(@ARGV); } elsif ($action =~ m[^remove-s]i) { removeSystemFromConfigDB(@ARGV); @@ -150,6 +155,7 @@ else { change-group change-system change-vendor-os + list-attributes list-client list-export list-group @@ -184,7 +190,7 @@ sub parseKeyValueArgs } my $key = lc($1); my $value = $2; - if ($value =~ m{^(?:UNDEF|NULL|-)$}) { + if ($value eq '-') { $value = undef; } if (!grep { $_ eq $key } @$allowedKeys) { @@ -212,7 +218,7 @@ sub parseKeyValueArgsWithAttrs } my $key = lc($1); my $value = $2; - if ($value =~ m{^(?:UNDEF|NULL|-)$}) { + if ($value eq '-') { $value = undef; } if (grep { $_ eq $key } @$allowedKeys) { @@ -224,7 +230,33 @@ sub parseKeyValueArgsWithAttrs } } - return (\%dataHash, \%attrHash); + if (wantarray) { + return (\%dataHash, \%attrHash); + } + else { + if (%attrHash) { + $dataHash{attrs} = \%attrHash; + } + return \%dataHash; + } +} + +sub mergeNonExistingAttributes +{ + my $target = shift; + my $source = shift; + + my $sourceAttrs = $source->{attrs} || {}; + + $target->{attrs} ||= {}; + my $targetAttrs = $target->{attrs}; + + foreach my $key (keys %$sourceAttrs) { + next if exists $targetAttrs->{$key}; + $targetAttrs->{$key} = $sourceAttrs->{$key}; + } + + return 1; } sub dumpElements @@ -266,7 +298,11 @@ sub dumpElements sort { my $refCmp = ref($elem->{$a}) cmp ref($elem->{$b}); return $refCmp ? $refCmp : $a cmp $b; - } keys %$elem + } + grep { + $_ ne 'name'; + } + keys %$elem ); } } @@ -277,6 +313,30 @@ sub dumpElements return 1; } +sub listAttributes +{ + my $name = shift; + + # always set verbose in order to give descriptive info + $verbose = 1; + + my $attrInfo = OpenSLX::AttributeRoster->getAttrInfo($name); + if (!defined $attrInfo) { + die _tr('attribute "%s" is unknown!', $name); + } + dumpElements( + 'attribute', undef, + map { + my $attr = dclone($attrInfo->{$_}); + $attr->{name} = $_; + $attr; + } + sort keys %$attrInfo + ); + + return 1; +} + sub listClients { my $name = _cleanName(shift); @@ -323,7 +383,7 @@ sub listGroups } dumpElements( - 'groups', undef, + 'group', undef, map { my @systemIDs = $openslxDB->fetchSystemIDsOfGroup($_->{id}); $_->{systems} @@ -440,7 +500,7 @@ sub listVendorOSes sub searchClients { my @clientKeys = $openslxDB->getColumnsOfTable('client'); - my @clientAttrKeys = $openslxDB->getKnownClientAttrs(); + my @clientAttrKeys = OpenSLX::AttributeRoster->getClientAttrs(); my ($clientData, $clientAttrs) = parseKeyValueArgsWithAttrs( \@clientKeys, \@clientAttrKeys, 'client', @_ ); @@ -471,7 +531,7 @@ sub searchClients sub searchGroups { my @groupKeys = $openslxDB->getColumnsOfTable('groups'); - my @groupAttrKeys = $openslxDB->getKnownClientAttrs(); + my @groupAttrKeys = OpenSLX::AttributeRoster->getClientAttrs(); my ($groupData, $groupAttrs) = parseKeyValueArgsWithAttrs( \@groupKeys, \@groupAttrKeys, 'group', @_ ); @@ -537,7 +597,7 @@ sub searchExports sub searchSystems { my @systemKeys = $openslxDB->getColumnsOfTable('system'); - my @systemAttrKeys = $openslxDB->getKnownSystemAttrs(); + my @systemAttrKeys = OpenSLX::AttributeRoster->getSystemAttrs(); my ($systemData, $systemAttrs) = parseKeyValueArgsWithAttrs( \@systemKeys, \@systemAttrKeys, 'system', @_ ); @@ -651,7 +711,10 @@ sub addClientToConfigDB my @clientKeys = $openslxDB->getColumnsOfTable('client'); push @clientKeys, 'systems'; - my $clientData = parseKeyValueArgs(\@clientKeys, 'client', @_); + my @clientAttrKeys = OpenSLX::AttributeRoster->getClientAttrs(); + my $clientData = parseKeyValueArgsWithAttrs( + \@clientKeys, \@clientAttrKeys, 'client', @_ + ); $clientData->{name} = $clientName; my @systemIDs; @@ -709,14 +772,16 @@ sub addClientToConfigDB sub addGroupToConfigDB { my $groupName = _cleanName(shift || ''); - if (!length($groupName)) { die _tr("you have to specify the name for the new group\n"); } my @groupKeys = $openslxDB->getColumnsOfTable('groups'); push @groupKeys, 'systems', 'clients'; - my $groupData = parseKeyValueArgs(\@groupKeys, 'groups', @_); + my @groupAttrKeys = OpenSLX::AttributeRoster->getClientAttrs(); + my $groupData = parseKeyValueArgsWithAttrs( + \@groupKeys, \@groupAttrKeys, 'group', @_ + ); $groupData->{name} = $groupName; my @systemIDs; @@ -784,8 +849,12 @@ sub addSystemToConfigDB my @systemKeys = $openslxDB->getColumnsOfTable('system'); push @systemKeys, 'clients', 'export'; - my $systemData = parseKeyValueArgs(\@systemKeys, 'system', @_); + my @systemAttrKeys = OpenSLX::AttributeRoster->getSystemAttrs(); + my $systemData = parseKeyValueArgsWithAttrs( + \@systemKeys, \@systemAttrKeys, 'system', @_ + ); $systemData->{name} = $systemName; + $systemData->{attrs} ||= {}; my $exportName = $systemData->{export} || ''; delete $systemData->{export}; @@ -827,21 +896,19 @@ sub addSystemToConfigDB $systemName); } + # activate kdm and X if system is based on kde: if ($systemName =~ m[\bkde\b]) { - - # activate kdm and X if system is based on kde: - $systemData->{attr_start_xdmcp} = 'kdm' - unless exists $systemData->{attr_start_xdmcp}; - $systemData->{attr_start_x} = 'yes' - unless exists $systemData->{attr_start_x}; + $systemData->{attrs}->{start_xdmcp} = 'kdm' + unless exists $systemData->{attrs}->{start_xdmcp}; + $systemData->{attrs}->{start_x} = 'yes' + unless exists $systemData->{attrs}->{start_x}; } + # activate gdm and X if system is based on GNOME: if ($systemName =~ m[\bgnome\b]) { - - # activate gdm and X if system is based on GNOME: - $systemData->{attr_start_xdmcp} = 'gdm' - unless exists $systemData->{attr_start_xdmcp}; - $systemData->{attr_start_x} = 'yes' - unless exists $systemData->{attr_start_x}; + $systemData->{attrs}->{start_xdmcp} = 'gdm' + unless exists $systemData->{attrs}->{start_xdmcp}; + $systemData->{attrs}->{start_x} = 'yes' + unless exists $systemData->{attrs}->{start_x}; } my $systemConfigPath = @@ -882,7 +949,10 @@ sub changeClientInConfigDB my @clientKeys = $openslxDB->getColumnsOfTable('client'); push @clientKeys, 'systems', 'add-systems', 'remove-systems'; - my $clientData = parseKeyValueArgs(\@clientKeys, 'client', @_); + my @clientAttrKeys = OpenSLX::AttributeRoster->getClientAttrs(); + my $clientData = parseKeyValueArgsWithAttrs( + \@clientKeys, \@clientAttrKeys, 'client', @_ + ); my $client = $openslxDB->fetchClientByFilter({'name' => $clientName}); if (!defined $client) { @@ -966,7 +1036,10 @@ sub changeGroupInConfigDB push @groupKeys, qw( systems add-systems remove-systems clients add-clients remove-clients ); - my $groupData = parseKeyValueArgs(\@groupKeys, 'group', @_); + my @groupAttrKeys = OpenSLX::AttributeRoster->getClientAttrs(); + my $groupData = parseKeyValueArgsWithAttrs( + \@groupKeys, \@groupAttrKeys, 'group', @_ + ); my $group = $openslxDB->fetchGroupByFilter({'name' => $groupName}); if (!defined $group) { @@ -974,6 +1047,8 @@ sub changeGroupInConfigDB $groupName); } + mergeNonExistingAttributes($groupData, $group); + my (@systemIDs, @clientIDs); if (exists $groupData->{systems}) { @systemIDs = map { @@ -1077,7 +1152,10 @@ sub changeSystemInConfigDB my @systemKeys = $openslxDB->getColumnsOfTable('system'); push @systemKeys, 'clients', 'add-clients', 'remove-clients'; - my $systemData = parseKeyValueArgs(\@systemKeys, 'system', @_); + my @systemAttrKeys = OpenSLX::AttributeRoster->getSystemAttrs(); + my $systemData = parseKeyValueArgsWithAttrs( + \@systemKeys, \@systemAttrKeys, 'system', @_ + ); my $system = $openslxDB->fetchSystemByFilter({'name' => $systemName}); if (!defined $system) { @@ -1166,7 +1244,7 @@ sub removeClientFromConfigDB return 1; } -sub removegroupFromConfigDB +sub removeGroupFromConfigDB { my $groupName = _cleanName(shift || ''); @@ -1176,7 +1254,7 @@ sub removegroupFromConfigDB ); } - my $groupData = parseKeyValueArgs(['name'], 'groups', @_); + my $groupData = parseKeyValueArgs(['name'], 'group', @_); my $group = $openslxDB->fetchGroupByFilter({'name' => $groupName}); if (!defined $group) { @@ -1268,7 +1346,7 @@ adds a new group to the config-DB =item B<< change-vendor-os [= ...] >> -changes the data of an existing vendor-OS in the config-DB +changes the data of an existing vendor-OS in the config-DB. =item B<< change-export [= ...] >> @@ -1278,14 +1356,27 @@ changes the data of an existing export in the config-DB changes the data of an existing client in the config-DB +Note: you can use the special value '-' to unset a key (mostly useful +for attributes). + =item B<< change-group [= ...] >> changes the data of an existing group in the config-DB +Note: you can use the special value '-' to unset a key (mostly useful +for attributes). + =item B<< change-system [= ...] >> changes the data of an existing system in the config-DB +Note: you can use the special value '-' to unset a key (mostly useful +for attributes). + +=item B<< list-attributes [] >> + +lists all attributes or the one with the given name + =item B<< list-client [] >> lists client with given name @@ -1389,6 +1480,16 @@ lists all existing instances of the respective DB-objects. =back +=head3 Listing known attributes + +=over 8 + +=item B<< slxconfig list-attr >> + +lists all known attributes (--verbose will give details). + +=back + =head3 Adding a new System to an exported Vendor-OS =over 8 @@ -1426,7 +1527,7 @@ associated with this client, yet (so it can't boot anything). =item B<< systems=suse-10.1,debian-4.0 \ >> -=item B<< attr_start_x=no >> +=item B<< 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' & @@ -1442,10 +1543,11 @@ During boot, the X-server will not be started by this client =over 8 -=item B<< slxconfig change-system suse-10.1 attr_start_xdmcp=gnome >> +=item B<< slxconfig change-system suse-10.1 start_xdmcp=gnome vmware=- >> will change the system named 'suse-10.1' such that it will use -the GNOME session manager. +the GNOME session manager. The attribute vmware is set to undefined (such that +it will be inherited from the default system) =item B<< slxconfig change-system suse-10.1 add-clients=vmware-1 >> @@ -1463,7 +1565,7 @@ will remove the client 'vmware-1' from the system named =over 8 -=item B<< slxconfig change-client PC131 attr_start_snmp=yes >> +=item B<< slxconfig change-client PC131 start_snmp=yes >> will change the client named 'PC131' such that it will start the SNMP daemon on all systems that it boots. diff --git a/config-db/slxconfig-demuxer b/config-db/slxconfig-demuxer index c71be64d..5019cab9 100755 --- a/config-db/slxconfig-demuxer +++ b/config-db/slxconfig-demuxer @@ -75,6 +75,10 @@ my ( $versionReq, ); +if ($> != 0) { + die _tr("Sorry, this script can only be executed by the superuser!\n"); +} + GetOptions( 'dhcp-export-type=s' => \$dhcpType, 'dry-run' => \$dryRun, @@ -85,9 +89,9 @@ GetOptions( 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 + $ENV{LC_MESSAGES} = 'POSIX'; pod2usage(-verbose => 2); } if ($versionReq) { @@ -120,7 +124,7 @@ if (createConfigFolderForDefaultSystem()) { my $lockFile = "$openslxConfig{'private-path'}/config-demuxer.lock"; lockScript($lockFile); -END { unlockScript($lockFile); } +END { unlockScript($lockFile) if defined $lockFile; } my $tempPath = "$openslxConfig{'temp-path'}/slxconfig-demuxer"; if (!$dryRun) { @@ -217,16 +221,15 @@ sub folderContainsFiles sub digestAttributes { # returns a digest-string for the given attribute hash, in order to # facilitate comparing different attribute hashes. - my $attrs = shift; + my $object = shift; + my $attrs = $object->{attrs} || {}; my $attrsAsString - = join ';', - map { - my $val = $attrs->{$_} || ''; - "$_=$val"; - } - sort { $a cmp $b } - grep { isAttribute($_) } keys %$attrs; + = join ';', + map { "$_=$attrs->{$_}" } + sort + grep { defined $attrs->{$_} } + keys %$attrs; vlog(3, "Attribute-string: $attrsAsString"); use Digest::MD5 qw(md5_hex); @@ -235,19 +238,15 @@ sub digestAttributes sub writeAttributesToFile { - my $attrHash = shift; + my $object = shift; my $fileName = shift; - my $grepForAttributes = shift; return if $dryRun; my $content = "# attributes set by slxconfig-demuxer:\n"; - my @attrs - = $grepForAttributes - ? grep { isAttribute($_) } sort keys %$attrHash - : sort keys %$attrHash; - foreach my $attr (@attrs) { - my $attrVal = $attrHash->{$attr} || ''; + my $attrs = $object->{attrs} || {}; + foreach my $attr (sort keys %$attrs) { + my $attrVal = $attrs->{$attr} || ''; if (length($attrVal) > 0) { my $externalAttrName = externalAttrName($attr); $content .= qq[$externalAttrName="$attrVal"\n]; @@ -449,13 +448,15 @@ sub generateInitalRamFS # generate initramfs-setup file (with settings relevant for initramfs only): my $initramfsAttrFile = "$tempPath/initramfs-setup"; my $initramfsAttrs = { - 'host_name' => 'slx-client', # silly default just to have something - 'ramfs_fsmods' => $info->{'attr_ramfs_fsmods'} || '', - 'ramfs_nicmods' => $info->{'attr_ramfs_nicmods'} || '', - 'ramfs_screen' => $info->{'attr_ramfs_screen'} || '', - 'rootfs' => $info->{'export-uri'} || '', + attrs => { + 'host_name' => 'slx-client', # just to have something at all + 'ramfs_fsmods' => $info->{'attr_ramfs_fsmods'} || '', + 'ramfs_nicmods' => $info->{'attr_ramfs_nicmods'} || '', + 'ramfs_screen' => $info->{'attr_ramfs_screen'} || '', + 'rootfs' => $info->{'export-uri'} || '', + }, }; - writeAttributesToFile($initramfsAttrs, $initramfsAttrFile, 0); + writeAttributesToFile($initramfsAttrs, $initramfsAttrFile); # and pass the generated initramfs-setup file to mkdxsinitrd: $cmd .= "-c $initramfsAttrFile "; @@ -502,7 +503,7 @@ sub writeSystemPXEFiles sub writeDhcpConfig { vlog(0, _tr("sorry, exporting dhcp data is not implemented yet!")); - my $dhcpModule = "OpenSLX::Export::DHCP::$dhcpType"; + my $dhcpModule = "OpenSLX::ConfigExport::DHCP::$dhcpType"; if (!eval { require $dhcpModule } ) { die _tr("unable to load DHCP-Export backend '%s'! (%s)\n", $dhcpModule, $@); @@ -562,7 +563,7 @@ sub writeClientConfigurationsForSystem copyExternalSystemConfig($externalSystemID, $buildPath, $externalClientName); - writeAttributesToFile($client, $attrFile, 1); + writeAttributesToFile($client, $attrFile); # create tar containing external system configuration # and client attribute file, this time referring to the client @@ -649,7 +650,7 @@ sub writeSystemConfiguration ) ); my $attrFile = "$buildPath/initramfs/machine-setup"; - writeAttributesToFile($info, $attrFile, 1); + writeAttributesToFile($info, $attrFile); writePluginConfigurationsForSystem($info, $buildPath); diff --git a/config-db/t/12-system.t b/config-db/t/12-system.t index 7a3e5e1e..dc8670de 100644 --- a/config-db/t/12-system.t +++ b/config-db/t/12-system.t @@ -368,6 +368,33 @@ is($system1->{name}, q{SYS-'1'}, q{really got system named "SYS-'1'"}); # changing nothing at all should succeed ok($configDB->changeSystem(1), 'changing nothing at all in system 1'); +# adding attributes should work +$inSystem1->{attrs}->{slxgrp} = 'slxgrp1'; +$inSystem1->{attrs}->{vmware} = 'yes'; +ok($configDB->changeSystem(1, $inSystem1), 'adding attrs to system 1'); +$system1 = $configDB->fetchSystemByID(1); +is($system1->{attrs}->{slxgrp}, 'slxgrp1', 'attr slxgrp has correct value'); +is($system1->{attrs}->{vmware}, 'yes', 'attr vmware has correct value'); + +# changing an attribute should work +$inSystem1->{attrs}->{vmware} = 'no'; +ok($configDB->changeSystem(1, $inSystem1), 'changing vmware in system 1'); +$system1 = $configDB->fetchSystemByID(1); +is($system1->{attrs}->{slxgrp}, 'slxgrp1', 'attr slxgrp has correct value'); +is($system1->{attrs}->{vmware}, 'no', 'attr vmware has correct value'); + +# deleting an attribute should remove it +delete $inSystem1->{attrs}->{slxgrp}; +ok($configDB->changeSystem(1, $inSystem1), 'changing slxgrp in system 1'); +$system1 = $configDB->fetchSystemByID(1); +ok(!exists $system1->{attrs}->{slxgrp}, 'attr slxgrp should be gone'); + +# undef'ing an attribute should remove it, too +$inSystem1->{attrs}->{vmware} = undef; +ok($configDB->changeSystem(1, $inSystem1), 'undefining vmware in system 1'); +$system1 = $configDB->fetchSystemByID(1); +ok(!exists $system1->{attrs}->{vmware}, 'attr vmware should be gone'); + # changing a non-existing column should fail ok( ! eval { $configDB->changeSystem(1, { xname => "xx" }) }, diff --git a/config-db/t/13-client.t b/config-db/t/13-client.t index 5848ba53..1c8ea99f 100644 --- a/config-db/t/13-client.t +++ b/config-db/t/13-client.t @@ -357,6 +357,33 @@ is($client1->{name}, q{CLI-'1'}, q{really got client named "CLI-'1'"}); # changing nothing at all should succeed ok($configDB->changeClient(1), 'changing nothing at all in client 1'); +# adding attributes should work +$inClient1->{attrs}->{slxgrp} = 'slxgrp1'; +$inClient1->{attrs}->{vmware} = 'yes'; +ok($configDB->changeClient(1, $inClient1), 'adding attrs to client 1'); +$client1 = $configDB->fetchClientByID(1); +is($client1->{attrs}->{slxgrp}, 'slxgrp1', 'attr slxgrp has correct value'); +is($client1->{attrs}->{vmware}, 'yes', 'attr vmware has correct value'); + +# changing an attribute should work +$inClient1->{attrs}->{vmware} = 'no'; +ok($configDB->changeClient(1, $inClient1), 'changing vmware in client 1'); +$client1 = $configDB->fetchClientByID(1); +is($client1->{attrs}->{slxgrp}, 'slxgrp1', 'attr slxgrp has correct value'); +is($client1->{attrs}->{vmware}, 'no', 'attr vmware has correct value'); + +# deleting an attribute should remove it +delete $inClient1->{attrs}->{slxgrp}; +ok($configDB->changeClient(1, $inClient1), 'changing slxgrp in client 1'); +$client1 = $configDB->fetchClientByID(1); +ok(!exists $client1->{attrs}->{slxgrp}, 'attr slxgrp should be gone'); + +# undef'ing an attribute should remove it, too +$inClient1->{attrs}->{vmware} = undef; +ok($configDB->changeClient(1, $inClient1), 'undefining vmware in client 1'); +$client1 = $configDB->fetchClientByID(1); +ok(!exists $client1->{attrs}->{vmware}, 'attr vmware should be gone'); + # changing a non-existing column should fail ok( ! eval { $configDB->changeClient(1, { xname => "xx" }) }, diff --git a/config-db/t/14-group.t b/config-db/t/14-group.t index 59530257..b06620ce 100644 --- a/config-db/t/14-group.t +++ b/config-db/t/14-group.t @@ -339,6 +339,33 @@ is($group1->{name}, q{GRP-'1'}, q{really got group named "GRP-'1'"}); # changing nothing at all should succeed ok($configDB->changeGroup(1), 'changing nothing at all in group 1'); +# adding attributes should work +$inGroup1->{attrs}->{slxgrp} = 'slxgrp1'; +$inGroup1->{attrs}->{vmware} = 'yes'; +ok($configDB->changeGroup(1, $inGroup1), 'adding attrs to group 1'); +$group1 = $configDB->fetchGroupByID(1); +is($group1->{attrs}->{slxgrp}, 'slxgrp1', 'attr slxgrp has correct value'); +is($group1->{attrs}->{vmware}, 'yes', 'attr vmware has correct value'); + +# changing an attribute should work +$inGroup1->{attrs}->{vmware} = 'no'; +ok($configDB->changeGroup(1, $inGroup1), 'changing vmware in group 1'); +$group1 = $configDB->fetchGroupByID(1); +is($group1->{attrs}->{slxgrp}, 'slxgrp1', 'attr slxgrp has correct value'); +is($group1->{attrs}->{vmware}, 'no', 'attr vmware has correct value'); + +# deleting an attribute should remove it +delete $inGroup1->{attrs}->{slxgrp}; +ok($configDB->changeGroup(1, $inGroup1), 'changing slxgrp in group 1'); +$group1 = $configDB->fetchGroupByID(1); +ok(!exists $group1->{attrs}->{slxgrp}, 'attr slxgrp should be gone'); + +# undef'ing an attribute should remove it, too +$inGroup1->{attrs}->{vmware} = undef; +ok($configDB->changeGroup(1, $inGroup1), 'undefining vmware in group 1'); +$group1 = $configDB->fetchGroupByID(1); +ok(!exists $group1->{attrs}->{vmware}, 'attr vmware should be gone'); + # changing a non-existing column should fail ok( ! eval { $configDB->changeGroup(1, { xname => "xx" }) }, diff --git a/config-db/t/25-attributes.t b/config-db/t/25-attributes.t index ce83d037..0a83afa9 100644 --- a/config-db/t/25-attributes.t +++ b/config-db/t/25-attributes.t @@ -5,6 +5,8 @@ use warnings; use lib '/opt/openslx/lib'; +use Storable qw(dclone); + # basic init use OpenSLX::ConfigDB qw(:support); @@ -12,25 +14,25 @@ my $configDB = OpenSLX::ConfigDB->new; $configDB->connect(); my $defaultAttrs = { # mostly copied from DBSchema - 'ramfs_fsmods' => '', - 'ramfs_miscmods' => '', + 'ramfs_fsmods' => undef, + 'ramfs_miscmods' => undef, 'ramfs_nicmods' => 'forcedeth e1000 e100 tg3 via-rhine r8169 pcnet32', - 'ramfs_screen' => '', + 'ramfs_screen' => undef, - 'automnt_dir' => '', - 'automnt_src' => '', + 'automnt_dir' => undef, + 'automnt_src' => undef, 'country' => 'de', 'dm_allow_shutdown' => 'user', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, 'late_dm' => 'no', 'netbios_workgroup' => 'slx-network', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', - 'scratch' => '', - 'slxgrp' => '', + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, + 'scratch' => undef, + 'slxgrp' => undef, 'start_alsasound' => 'yes', 'start_atd' => 'no', 'start_cron' => 'no', @@ -128,24 +130,24 @@ ok( # default client attributes: my $shouldBeAttrs1 = { 'ramfs_fsmods' => 'squashfs', - 'ramfs_miscmods' => '', + 'ramfs_miscmods' => undef, 'ramfs_nicmods' => 'forcedeth e1000 r8169', - 'ramfs_screen' => '', + 'ramfs_screen' => undef, - 'automnt_dir' => '', - 'automnt_src' => '', + 'automnt_dir' => undef, + 'automnt_src' => undef, 'country' => 'de', 'dm_allow_shutdown' => 'user', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, 'late_dm' => 'no', 'netbios_workgroup' => 'slx-network', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', - 'scratch' => '', - 'slxgrp' => '', + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, + 'scratch' => undef, + 'slxgrp' => undef, 'start_alsasound' => 'yes', 'start_atd' => 'no', 'start_cron' => 'no', @@ -272,45 +274,45 @@ ok( ); # check merging of attributes into client, the order should be: -# default client attributes overruled by group attributes (ordererd by priority) +# default client attributes overruled by group attributes (ordered by priority) # overruled by specific client attributes: $shouldBeAttrs1 = { - 'ramfs_fsmods' => '', - 'ramfs_miscmods' => '', - 'ramfs_nicmods' => '', - 'ramfs_screen' => '', - - 'automnt_dir' => '', - 'automnt_src' => '', - 'country' => '', - 'dm_allow_shutdown' => '', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', - 'late_dm' => '', - 'netbios_workgroup' => '', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', + 'ramfs_fsmods' => undef, + 'ramfs_miscmods' => undef, + 'ramfs_nicmods' => undef, + 'ramfs_screen' => undef, + + 'automnt_dir' => undef, + 'automnt_src' => undef, + 'country' => undef, + 'dm_allow_shutdown' => undef, + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, + 'late_dm' => undef, + 'netbios_workgroup' => undef, + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, 'scratch' => '/dev/sdx3', - 'slxgrp' => '', - 'start_alsasound' => '', - 'start_atd' => '', - 'start_cron' => '', - 'start_dreshal' => '', - 'start_ntp' => '', - 'start_nfsv4' => '', - 'start_printer' => '', - 'start_samba' => '', + 'slxgrp' => undef, + 'start_alsasound' => undef, + 'start_atd' => undef, + 'start_cron' => undef, + 'start_dreshal' => undef, + 'start_ntp' => undef, + 'start_nfsv4' => undef, + 'start_printer' => undef, + 'start_samba' => undef, 'start_snmp' => 'yes', - 'start_sshd' => '', - 'start_syslog' => '', - 'start_x' => '', - 'start_xdmcp' => '', - 'tex_enable' => '', + 'start_sshd' => undef, + 'start_syslog' => undef, + 'start_x' => undef, + 'start_xdmcp' => undef, + 'tex_enable' => undef, 'timezone' => 'America/New_York', - 'tvout' => '', - 'vmware' => '', + 'tvout' => undef, + 'vmware' => undef, }; my $mergedClient1 = $configDB->fetchClientByID(1); ok( @@ -319,48 +321,48 @@ ok( ); foreach my $key (sort keys %$shouldBeAttrs1) { is( - $mergedClient1->{attrs}->{$key} || '', $shouldBeAttrs1->{$key} || '', + $mergedClient1->{attrs}->{$key}, $shouldBeAttrs1->{$key}, "checking merged attribute $key for client 1" ); } $shouldBeAttrs3 = { - 'ramfs_fsmods' => '', - 'ramfs_miscmods' => '', - 'ramfs_nicmods' => '', - 'ramfs_screen' => '', - - 'automnt_dir' => '', - 'automnt_src' => '', - 'country' => '', - 'dm_allow_shutdown' => '', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', - 'late_dm' => '', - 'netbios_workgroup' => '', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', - 'scratch' => '', - 'slxgrp' => '', - 'start_alsasound' => '', - 'start_atd' => '', - 'start_cron' => '', - 'start_dreshal' => '', - 'start_ntp' => '', - 'start_nfsv4' => '', - 'start_printer' => '', - 'start_samba' => '', + 'ramfs_fsmods' => undef, + 'ramfs_miscmods' => undef, + 'ramfs_nicmods' => undef, + 'ramfs_screen' => undef, + + 'automnt_dir' => undef, + 'automnt_src' => undef, + 'country' => undef, + 'dm_allow_shutdown' => undef, + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, + 'late_dm' => undef, + 'netbios_workgroup' => undef, + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, + 'scratch' => undef, + 'slxgrp' => undef, + 'start_alsasound' => undef, + 'start_atd' => undef, + 'start_cron' => undef, + 'start_dreshal' => undef, + 'start_ntp' => undef, + 'start_nfsv4' => undef, + 'start_printer' => undef, + 'start_samba' => undef, 'start_snmp' => 'yes', - 'start_sshd' => '', - 'start_syslog' => '', - 'start_x' => '', - 'start_xdmcp' => '', - 'tex_enable' => '', + 'start_sshd' => undef, + 'start_syslog' => undef, + 'start_x' => undef, + 'start_xdmcp' => undef, + 'tex_enable' => undef, 'timezone' => 'Europe/London', - 'tvout' => '', - 'vmware' => '', + 'tvout' => undef, + 'vmware' => undef, }; # remove all attributes from client 3 @@ -373,7 +375,7 @@ ok( ); foreach my $key (sort keys %$shouldBeAttrs1) { is( - $mergedClient3->{attrs}->{$key} || '', $shouldBeAttrs3->{$key} || '', + $mergedClient3->{attrs}->{$key}, $shouldBeAttrs3->{$key}, "checking merged attribute $key for client 3" ); } @@ -384,41 +386,41 @@ ok( 'group-IDs of default client have been set' ); $shouldBeAttrs1 = { - 'ramfs_fsmods' => '', - 'ramfs_miscmods' => '', - 'ramfs_nicmods' => '', - 'ramfs_screen' => '', - - 'automnt_dir' => '', - 'automnt_src' => '', - 'country' => '', - 'dm_allow_shutdown' => '', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', - 'late_dm' => '', - 'netbios_workgroup' => '', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', + 'ramfs_fsmods' => undef, + 'ramfs_miscmods' => undef, + 'ramfs_nicmods' => undef, + 'ramfs_screen' => undef, + + 'automnt_dir' => undef, + 'automnt_src' => undef, + 'country' => undef, + 'dm_allow_shutdown' => undef, + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, + 'late_dm' => undef, + 'netbios_workgroup' => undef, + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, 'scratch' => '/dev/sdx3', - 'slxgrp' => '', - 'start_alsasound' => '', - 'start_atd' => '', - 'start_cron' => '', - 'start_dreshal' => '', - 'start_ntp' => '', - 'start_nfsv4' => '', - 'start_printer' => '', - 'start_samba' => '', + 'slxgrp' => undef, + 'start_alsasound' => undef, + 'start_atd' => undef, + 'start_cron' => undef, + 'start_dreshal' => undef, + 'start_ntp' => undef, + 'start_nfsv4' => undef, + 'start_printer' => undef, + 'start_samba' => undef, 'start_snmp' => 'yes', - 'start_sshd' => '', - 'start_syslog' => '', - 'start_x' => '', - 'start_xdmcp' => '', - 'tex_enable' => '', + 'start_sshd' => undef, + 'start_syslog' => undef, + 'start_x' => undef, + 'start_xdmcp' => undef, + 'tex_enable' => undef, 'timezone' => 'America/New_York', - 'tvout' => '', + 'tvout' => undef, 'vmware' => 'yes', }; $mergedClient1 = $configDB->fetchClientByID(1); @@ -428,47 +430,47 @@ ok( ); foreach my $key (sort keys %$shouldBeAttrs1) { is( - $mergedClient1->{attrs}->{$key} || '', $shouldBeAttrs1->{$key} || '', + $mergedClient1->{attrs}->{$key}, $shouldBeAttrs1->{$key}, "checking merged attribute $key for client 1" ); } $shouldBeAttrs3 = { - 'ramfs_fsmods' => '', - 'ramfs_miscmods' => '', - 'ramfs_nicmods' => '', - 'ramfs_screen' => '', - - 'automnt_dir' => '', - 'automnt_src' => '', - 'country' => '', - 'dm_allow_shutdown' => '', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', - 'late_dm' => '', - 'netbios_workgroup' => '', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', + 'ramfs_fsmods' => undef, + 'ramfs_miscmods' => undef, + 'ramfs_nicmods' => undef, + 'ramfs_screen' => undef, + + 'automnt_dir' => undef, + 'automnt_src' => undef, + 'country' => undef, + 'dm_allow_shutdown' => undef, + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, + 'late_dm' => undef, + 'netbios_workgroup' => undef, + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, 'scratch' => '/dev/hdd1', - 'slxgrp' => '', - 'start_alsasound' => '', - 'start_atd' => '', - 'start_cron' => '', - 'start_dreshal' => '', - 'start_ntp' => '', - 'start_nfsv4' => '', - 'start_printer' => '', - 'start_samba' => '', + 'slxgrp' => undef, + 'start_alsasound' => undef, + 'start_atd' => undef, + 'start_cron' => undef, + 'start_dreshal' => undef, + 'start_ntp' => undef, + 'start_nfsv4' => undef, + 'start_printer' => undef, + 'start_samba' => undef, 'start_snmp' => 'yes', - 'start_sshd' => '', - 'start_syslog' => '', - 'start_x' => '', - 'start_xdmcp' => '', - 'tex_enable' => '', + 'start_sshd' => undef, + 'start_syslog' => undef, + 'start_x' => undef, + 'start_xdmcp' => undef, + 'tex_enable' => undef, 'timezone' => 'Europe/London', - 'tvout' => '', + 'tvout' => undef, 'vmware' => 'yes', }; $mergedClient3 = $configDB->fetchClientByID(3); @@ -478,37 +480,37 @@ ok( ); foreach my $key (sort keys %$shouldBeAttrs1) { is( - $mergedClient3->{attrs}->{$key} || '', $shouldBeAttrs3->{$key} || '', + $mergedClient3->{attrs}->{$key}, $shouldBeAttrs3->{$key}, "checking merged attribute $key for client 3" ); } # finally we merge systems into clients and check the outcome of that -my $fullMerge11 = { %$mergedClient1 }; +my $fullMerge11 = dclone($mergedClient1); ok( mergeAttributes($fullMerge11, $mergedSystem1), 'merging system 1 into client 1' ); my $shouldBeAttrs11 = { 'ramfs_fsmods' => 'squashfs', - 'ramfs_miscmods' => '', + 'ramfs_miscmods' => undef, 'ramfs_nicmods' => 'forcedeth e1000 r8169', - 'ramfs_screen' => '', + 'ramfs_screen' => undef, - 'automnt_dir' => '', - 'automnt_src' => '', + 'automnt_dir' => undef, + 'automnt_src' => undef, 'country' => 'de', 'dm_allow_shutdown' => 'user', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, 'late_dm' => 'no', 'netbios_workgroup' => 'slx-network', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, 'scratch' => '/dev/sdx3', - 'slxgrp' => '', + 'slxgrp' => undef, 'start_alsasound' => 'yes', 'start_atd' => 'no', 'start_cron' => 'no', @@ -529,36 +531,36 @@ my $shouldBeAttrs11 = { }; foreach my $key (sort keys %$shouldBeAttrs11) { is( - $fullMerge11->{attrs}->{$key} || '', $shouldBeAttrs11->{$key} || '', + $fullMerge11->{attrs}->{$key}, $shouldBeAttrs11->{$key}, "checking merged attribute $key for client 1 / system 1" ); } -my $fullMerge31 = { %$mergedClient3 }; +my $fullMerge31 = dclone($mergedClient3); ok( mergeAttributes($fullMerge31, $mergedSystem1), 'merging system 1 into client 3' ); my $shouldBeAttrs31 = { 'ramfs_fsmods' => 'squashfs', - 'ramfs_miscmods' => '', + 'ramfs_miscmods' => undef, 'ramfs_nicmods' => 'forcedeth e1000 r8169', - 'ramfs_screen' => '', + 'ramfs_screen' => undef, - 'automnt_dir' => '', - 'automnt_src' => '', + 'automnt_dir' => undef, + 'automnt_src' => undef, 'country' => 'de', 'dm_allow_shutdown' => 'user', - 'hw_graphic' => '', - 'hw_monitor' => '', - 'hw_mouse' => '', + 'hw_graphic' => undef, + 'hw_monitor' => undef, + 'hw_mouse' => undef, 'late_dm' => 'no', 'netbios_workgroup' => 'slx-network', - 'nis_domain' => '', - 'nis_servers' => '', - 'sane_scanner' => '', + 'nis_domain' => undef, + 'nis_servers' => undef, + 'sane_scanner' => undef, 'scratch' => '/dev/hdd1', - 'slxgrp' => '', + 'slxgrp' => undef, 'start_alsasound' => 'yes', 'start_atd' => 'no', 'start_cron' => 'no', @@ -579,12 +581,12 @@ my $shouldBeAttrs31 = { }; foreach my $key (sort keys %$shouldBeAttrs31) { is( - $fullMerge31->{attrs}->{$key} || '', $shouldBeAttrs31->{$key} || '', + $fullMerge31->{attrs}->{$key}, $shouldBeAttrs31->{$key}, "checking merged attribute $key for client 3 / system 1" ); } -my $fullMerge13 = { %$mergedClient1 }; +my $fullMerge13 = dclone($mergedClient1); ok( mergeAttributes($fullMerge13, $mergedSystem3), 'merging system 3 into client 1' @@ -629,12 +631,12 @@ my $shouldBeAttrs13 = { }; foreach my $key (sort keys %$shouldBeAttrs13) { is( - $fullMerge13->{attrs}->{$key} || '', $shouldBeAttrs13->{$key} || '', + $fullMerge13->{attrs}->{$key}, $shouldBeAttrs13->{$key}, "checking merged attribute $key for client 1 / system 3" ); } -my $fullMerge33 = { %$mergedClient3 }; +my $fullMerge33 = dclone($mergedClient3); ok( mergeAttributes($fullMerge33, $mergedSystem3), 'merging system 3 into client 3' @@ -679,7 +681,7 @@ my $shouldBeAttrs33 = { }; foreach my $key (sort keys %$shouldBeAttrs33) { is( - $fullMerge33->{attrs}->{$key} || '', $shouldBeAttrs33->{$key} || '', + $fullMerge33->{attrs}->{$key}, $shouldBeAttrs33->{$key}, "checking merged attribute $key for client 3 / system 3" ); } -- cgit v1.2.3-55-g7522