summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-db/OpenSLX/AttributeRoster.pm71
-rwxr-xr-xconfig-db/slxconfig49
-rw-r--r--os-plugins/OpenSLX/OSPlugin/Base.pm26
-rw-r--r--os-plugins/OpenSLX/OSPlugin/Engine.pm40
-rw-r--r--os-plugins/OpenSLX/OSPlugin/Roster.pm6
-rw-r--r--os-plugins/plugins/desktop/OpenSLX/OSPlugin/desktop.pm112
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;