diff options
-rw-r--r-- | config-db/OpenSLX/AttributeRoster.pm | 71 | ||||
-rwxr-xr-x | config-db/slxconfig | 49 | ||||
-rw-r--r-- | os-plugins/OpenSLX/OSPlugin/Base.pm | 26 | ||||
-rw-r--r-- | os-plugins/OpenSLX/OSPlugin/Engine.pm | 40 | ||||
-rw-r--r-- | os-plugins/OpenSLX/OSPlugin/Roster.pm | 6 | ||||
-rw-r--r-- | os-plugins/plugins/desktop/OpenSLX/OSPlugin/desktop.pm | 112 |
6 files changed, 247 insertions, 57 deletions
diff --git a/config-db/OpenSLX/AttributeRoster.pm b/config-db/OpenSLX/AttributeRoster.pm index 331ac70c..13c7640d 100644 --- a/config-db/OpenSLX/AttributeRoster.pm +++ b/config-db/OpenSLX/AttributeRoster.pm @@ -17,6 +17,7 @@ use strict; use warnings; use OpenSLX::Basics; +use OpenSLX::OSPlugin::Engine; use OpenSLX::OSPlugin::Roster; use OpenSLX::Utils; @@ -370,6 +371,8 @@ sub _init # and add all plugin attributes, too OpenSLX::OSPlugin::Roster->addAllStage3AttributesToHash(\%AttributeInfo); + + return 1; } =item C<getAttrInfo()> @@ -495,43 +498,57 @@ sub getClientAttrs keys %AttributeInfo } -=item C<checkValueForKey()> +=item C<checkValues()> -Checks if the given value is allowed (and makes sense) for the given key. -If the value is ok, this method returns 1 - if not, it dies with an appropriate -message. +Checks if the given stage3 attribute values are allowed (and make sense). +If all values are ok, this method returns 1 - if not, it dies with an +appropriate message. =cut -sub checkValueForKey +sub checkValues { - my $class = shift; - my $key = shift; - my $value = shift; + my $class = shift; + my $stage3Attrs = shift || {}; + my $vendorOSName = shift or die ('need vendor-OS-name!'); $class->_init() if !%AttributeInfo; - # undefined values are always allowed - return 1 if !defined $value; - - # check the value against the regex of the attribute (if any) - my $attrInfo = $AttributeInfo{$key} - || die _tr('attribute "%s" is unknown!', $key); - my $regex = $attrInfo->{content_regex}; - if ($regex && $value !~ m{$regex}) { - die _tr( - "value given for attribute %s is not allowed.\nAllowed values are: %s", - $key, $attrInfo->{content_descr} - ); + my %attrsByPlugin; + foreach my $key (sort keys %{$stage3Attrs}) { + my $value = $stage3Attrs->{$key}; + if ($key =~ m{^(.+)::.+?$}) { + my $pluginName = $1; + $attrsByPlugin{$pluginName} ||= {}; + $attrsByPlugin{$pluginName}->{$key} = $value; + } + + # undefined values are always allowed + next if !defined $value; + + # check the value against the regex of the attribute (if any) + my $attrInfo = $AttributeInfo{$key} + || die _tr('attribute "%s" is unknown!', $key); + my $regex = $attrInfo->{content_regex}; + if ($regex && $value !~ $regex) { + die _tr( + "the value '%s' for attribute %s is not allowed.\nAllowed values are: %s", + $value, $key, $attrInfo->{content_descr} + ); + } } - # let plugin check by itself - if ($key =~ m{^(.+)::.+?$}) { - my $pluginName = $1; - my $plugin - = OpenSLX::OSPlugin::Roster->getPlugin($pluginName) - || die _tr('unable to load plugin "%s"', $pluginName); - $plugin->checkValueForKey($key, $value); + # now give each plugin a chance to check it's own attributes by itself + foreach my $pluginName (sort keys %attrsByPlugin) { + # create & start OSPlugin-engine for vendor-OS and current plugin + my $engine = OpenSLX::OSPlugin::Engine->new; + $engine->initialize($pluginName, $vendorOSName); + if (!$engine->{'plugin-path'}) { + warn _tr('unable to create engine for plugin "%s"!', $pluginName); + next; + } + $engine->checkStage3AttrValues($attrsByPlugin{$pluginName}); } } + 1; diff --git a/config-db/slxconfig b/config-db/slxconfig index 4414d2db..5592e06d 100755 --- a/config-db/slxconfig +++ b/config-db/slxconfig @@ -20,10 +20,10 @@ slxconfig and you can create clients for these systems, too. ]; +use Clone qw(clone); 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: @@ -247,7 +247,6 @@ sub parseKeyValueArgsWithAttrs if (grep { $_ eq $key } @$allowedKeys) { $dataHash{$key} = $value; } elsif (grep { $_ eq $key } @$allowedAttrKeys) { - OpenSLX::AttributeRoster->checkValueForKey($key, $value); $attrHash{$key} = $value; } else { die _tr("unknown key '%s' specified for %s\n", $key, $table); @@ -265,6 +264,18 @@ sub parseKeyValueArgsWithAttrs } } +sub checkGivenStage3Attrs +{ + my $stage3Attrs = shift; + my $vendorOSID = shift; + + my $vendorOS = $openslxDB->fetchVendorOSByID($vendorOSID); + + OpenSLX::AttributeRoster->checkValues($stage3Attrs, $vendorOS->{name}); + + return 1; +} + sub mergeNonExistingAttributes { my $target = shift; @@ -359,7 +370,7 @@ sub listAttributes dumpElements( 'attribute', undef, map { - my $attr = dclone($attrInfo->{$_}); + my $attr = clone($attrInfo->{$_}); $attr->{name} = $_; delete $attr->{content_regex}; # no use for display purposes $attr; @@ -488,7 +499,14 @@ sub listVendorOSes dumpElements('vendor-OS', undef, map { my @plugins = $openslxDB->fetchInstalledPlugins($_->{id}); - $_->{plugins} + my %attrHash; + foreach my $plugin (@plugins) { + foreach my $attr (keys %{$plugin->{attrs}}) { + $attrHash{$attr} = $plugin->{attrs}->{$attr}; + } + } + $_->{ATTRIBUTES} = \%attrHash; + $_->{PLUGINS} = @plugins ? join(',', sort map { $_->{plugin_name} } @plugins) : '<none>'; @@ -844,6 +862,8 @@ sub addSystemToConfigDB } $systemData->{export_id} = $export->{id}; + checkGivenStage3Attrs($systemData->{attrs}, $export->{vendor_os_id}); + my @clientIDs; if (exists $systemData->{clients}) { @clientIDs = map { @@ -1118,6 +1138,11 @@ sub changeSystemInConfigDB ); } + my $system = $openslxDB->fetchSystemByFilter({'name' => $systemName}); + if (!defined $system) { + die _tr("the system '%s' doesn't exists in the DB, giving up!\n", + $systemName); + } my @systemKeys = $openslxDB->getColumnsOfTable('system'); push @systemKeys, 'clients', 'add-clients', 'remove-clients'; my @systemAttrKeys = OpenSLX::AttributeRoster->getSystemAttrs(); @@ -1125,11 +1150,8 @@ sub changeSystemInConfigDB \@systemKeys, \@systemAttrKeys, 'system', @_ ); - my $system = $openslxDB->fetchSystemByFilter({'name' => $systemName}); - if (!defined $system) { - die _tr("the system '%s' doesn't exists in the DB, giving up!\n", - $systemName); - } + my $export = $openslxDB->fetchExportByID($system->{export_id}); + checkGivenStage3Attrs($systemData->{attrs}, $export->{vendor_os_id}); mergeNonExistingAttributes($systemData, $system); @@ -1276,7 +1298,7 @@ sub _expandClients sort { $a->{name} cmp $b->{name} } $openslxDB->fetchSystemByID(\@sysIDs, 'name'); if ($option{inherited}) { - my $mergedClient = dclone($_); + my $mergedClient = clone($_); my $originInfo = {}; $openslxDB->mergeDefaultAndGroupAttributesIntoClient( $mergedClient, $originInfo @@ -1325,21 +1347,20 @@ sub _expandSystems map { my @clientIDs = $openslxDB->fetchClientIDsOfSystem($_->{id}); $_->{clients} - = join "\n", + = join "\n", map { $_->{name} } sort { $a->{name} cmp $b->{name} } $openslxDB->fetchClientByID(\@clientIDs, 'name'); my @activePlugins; my $export = $openslxDB->fetchExportByID($_->{export_id}); if (defined $export) { - $_->{export_id} - = "$export->{id} ($export->{name})"; + $_->{export_id} = "$export->{id} ($export->{name})"; # fetch detailed info about active plugins my @installedPlugins = $openslxDB->fetchInstalledPlugins( $export->{vendor_os_id} ); - my $mergedSystem = dclone($_); + my $mergedSystem = clone($_); my $originInfo = {}; $openslxDB->mergeDefaultAttributesIntoSystem( $mergedSystem, \@installedPlugins, $originInfo diff --git a/os-plugins/OpenSLX/OSPlugin/Base.pm b/os-plugins/OpenSLX/OSPlugin/Base.pm index b89f73fa..8c314ff5 100644 --- a/os-plugins/OpenSLX/OSPlugin/Base.pm +++ b/os-plugins/OpenSLX/OSPlugin/Base.pm @@ -182,29 +182,33 @@ sub getDefaultAttrsForVendorOS return $self->getAttrInfo(); } -=item checkValueForKey() +=item checkStage3AttrValues() -Checks if the given value is allowed (and makes sense) for the given key. -If the value is ok, this method returns 1 - if not, it dies with an appropriate -message. +Checks if the stage3 values given in B<$stage3Attrs> are allowed and makes +sense. -Plugins may override this implementation to do checks that for instance look -at the vendor-OS (stage1-)attributes. +If all values are ok, this method returns 1 - if not, it dies with an appropriate message. + +Plugins may override this implementation to do checks that for instance look +at the stage1 vendor-OS-attributes given in B<$vendorOSAttrs>. + +N.B.: this method is called while being chrooted into the vendor-OS, so it + may invoke all distro methods that expect to be run in this environment, + too =cut -sub checkValueForKey +sub checkStage3AttrValues { - my $self = shift; - my $key = shift; - my $value = shift; + my $self = shift; + my $stage3Attrs = shift; + my $vendorOSAttrs = shift; # this default implementation does no further checks (thus relying on the # attributte regex check that is done in the AttributeRoster) return 1; } - =back =head2 Vendor-OS Interface diff --git a/os-plugins/OpenSLX/OSPlugin/Engine.pm b/os-plugins/OpenSLX/OSPlugin/Engine.pm index 0672aa5e..ada0af79 100644 --- a/os-plugins/OpenSLX/OSPlugin/Engine.pm +++ b/os-plugins/OpenSLX/OSPlugin/Engine.pm @@ -126,6 +126,7 @@ sub initialize ? $dbAttrs->{$attrName} : $defaultAttrs->{$attrName}->{default}; } + $self->{'vendorOS-attrs'} = $dbAttrs; } return 1; @@ -377,7 +378,6 @@ sub getInstallablePackagesForSelection ); } - =item installPackages($packages) Installs the given packages into the vendor-OS. @@ -447,6 +447,44 @@ sub removePackages =back +=head2 Driver Interface + +The following methods are invoked by the slxos-plugin script in order to +install/remove a plugin into/from a vendor-OS: + +=over + +=item checkStage3AttrValues() + +Checks if the stage3 values given in B<$stage3Attrs> are allowed and make sense. + +If all values are ok, this method returns 1 - if not, it dies with an +appropriate message. + +This method chroots into the vendor-OS and then asks the plugin itself to check +the attributes. + +=cut + +sub checkStage3AttrValues +{ + my $self = shift; + my $stage3Attrs = shift; + + $self->_callChrootedFunctionForPlugin( + sub { + # let plugin check by itself + $self->{plugin}->checkStage3AttrValues( + $stage3Attrs, $self->{'vendorOS-attrs'} + ); + } + ); + + return 1; +} + +=back + =cut sub _loadPlugin diff --git a/os-plugins/OpenSLX/OSPlugin/Roster.pm b/os-plugins/OpenSLX/OSPlugin/Roster.pm index 023abb4c..7bfed044 100644 --- a/os-plugins/OpenSLX/OSPlugin/Roster.pm +++ b/os-plugins/OpenSLX/OSPlugin/Roster.pm @@ -17,7 +17,7 @@ use strict; use warnings; use OpenSLX::Basics; -use Storable qw(dclone); +use Clone qw(clone); my %plugins; @@ -56,7 +56,7 @@ sub getPlugin my $plugin = $plugins{$pluginName}; return if !$plugin; - return dclone($plugin); + return clone($plugin); } =item C<getPluginAttrInfo()> @@ -179,7 +179,7 @@ sub _addAttributesToHash my $pluginAttrInfo = $plugin->getAttrInfo(); foreach my $attr (keys %$pluginAttrInfo) { next if !$testFunc->($pluginAttrInfo->{$attr}); - $attrInfo->{$attr} = dclone($pluginAttrInfo->{$attr}); + $attrInfo->{$attr} = clone($pluginAttrInfo->{$attr}); } } return 1; diff --git a/os-plugins/plugins/desktop/OpenSLX/OSPlugin/desktop.pm b/os-plugins/plugins/desktop/OpenSLX/OSPlugin/desktop.pm index 03c26454..92b1e9a9 100644 --- a/os-plugins/plugins/desktop/OpenSLX/OSPlugin/desktop.pm +++ b/os-plugins/plugins/desktop/OpenSLX/OSPlugin/desktop.pm @@ -53,6 +53,7 @@ sub getAttrInfo my $self = shift; return { + # stage3 'desktop::active' => { applies_to_systems => 1, applies_to_clients => 1, @@ -69,7 +70,7 @@ sub getAttrInfo description => unshiftHereDoc(<<' End-of-Here'), which display manager to start: gdm, kdm or xdm? End-of-Here - content_regex => qr{^(g|k|x)dm$}, + content_regex => qr{^(gdm|kdm|xdm)$}, content_descr => '"gdm", "kdm" or "xdm"', default => undef, }, @@ -103,6 +104,8 @@ sub getAttrInfo content_descr => 'one of the entries in "supported_themes"', default => 'openslx', }, + + # stage1 'desktop::supported_themes' => { applies_to_vendor_os => 1, description => unshiftHereDoc(<<' End-of-Here'), @@ -197,6 +200,113 @@ sub getDefaultAttrsForVendorOS return $attrs; } +sub checkStage3AttrValues +{ + my $self = shift; + my $stage3Attrs = shift; + my $vendorOSAttrs = shift; + + my $manager = $stage3Attrs->{'desktop::manager'} || ''; + if ($manager eq 'kdm') { + if (!defined $vendorOSAttrs->{'desktop::kdm'}) { + if (!$self->{distro}->isKDMInstalled()) { + die _tr( + "KDM is not installed in vendor-OS, so using it as desktop manager wouldn't work!" + ); + } + } + elsif ($vendorOSAttrs->{'desktop::kdm'} == 0) { + die _tr( + "desktop::kdm is 0, so using KDM as desktop manager is not allowed for this vendor-OS!" + ); + } + } + elsif ($manager eq 'gdm') { + if (!defined $vendorOSAttrs->{'desktop::gdm'}) { + if (!$self->{distro}->isGDMInstalled()) { + die _tr( + "GDM is not installed in vendor-OS, so using it as desktop manager wouldn't work!" + ); + } + } + elsif ($vendorOSAttrs->{'desktop::gdm'} == 0) { + die _tr( + "desktop::gdm is 0, so using GDM as desktop manager is not allowed for this vendor-OS!" + ); + } + } + elsif ($manager eq 'xdm') { + if (!defined $vendorOSAttrs->{'desktop::xdm'}) { + if (!$self->{distro}->isXDMInstalled()) { + die _tr( + "XDM is not installed in vendor-OS, so using it as desktop manager wouldn't work!" + ); + } + } + elsif ($vendorOSAttrs->{'desktop::xdm'} == 0) { + die _tr( + "desktop::xdm is 0, so using XDM as desktop manager is not allowed for this vendor-OS!" + ); + } + } + + my $kind = $stage3Attrs->{'desktop::kind'} || ''; + if ($kind eq 'kde') { + if (!defined $vendorOSAttrs->{'desktop::kde'}) { + if (!$self->{distro}->isKDEInstalled()) { + die _tr( + "KDE is not installed in vendor-OS, so using it as desktop kind wouldn't work!" + ); + } + } + elsif ($vendorOSAttrs->{'desktop::kde'} == 0) { + die _tr( + "desktop::kde is 0, so using KDE as desktop kind is not allowed for this vendor-OS!" + ); + } + } + elsif ($kind eq 'gnome') { + if (!defined $vendorOSAttrs->{'desktop::gnome'}) { + if (!$self->{distro}->isGNOMEInstalled()) { + die _tr( + "GNOME is not installed in vendor-OS, so using it as desktop kind wouldn't work!" + ); + } + } + elsif ($vendorOSAttrs->{'desktop::gnome'} == 0) { + die _tr( + "desktop::gnome is 0, so using GNOME as desktop kind is not allowed for this vendor-OS!" + ); + } + } + elsif ($kind eq 'xfce') { + if (!defined $vendorOSAttrs->{'desktop::xfce'}) { + if (!$self->{distro}->isXFCEInstalled()) { + die _tr( + "XFCE is not installed in vendor-OS, so using it as desktop kind wouldn't work!" + ); + } + } + elsif ($vendorOSAttrs->{'desktop::xfce'} == 0) { + die _tr( + "desktop::xfce is 0, so using XFCE as desktop kind is not allowed for this vendor-OS!" + ); + } + } + + my @supportedThemes + = split ',', $vendorOSAttrs->{'desktop::supported_themes'} || ''; + my $theme = $stage3Attrs->{'desktop::theme'}; + if (defined $theme && !grep { $_ eq $theme } @supportedThemes) { + die _tr( + "'%s' is not a supported theme!\nSupported themes are: %s", + $theme, $vendorOSAttrs->{'desktop::supported_themes'} || '' + ); + } + + return 1; +} + sub installationPhase { my $self = shift; |