summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfig-db/slxconfig-demuxer19
-rw-r--r--installer/OpenSLX/OSSetup/Engine.pm25
-rw-r--r--os-plugins/OpenSLX/OSPlugin/Base.pm47
-rw-r--r--os-plugins/OpenSLX/OSPlugin/Engine.pm82
-rw-r--r--os-plugins/plugins/vmchooser/OpenSLX/OSPlugin/vmchooser.pm1
-rwxr-xr-xos-plugins/slxos-plugin8
6 files changed, 178 insertions, 4 deletions
diff --git a/config-db/slxconfig-demuxer b/config-db/slxconfig-demuxer
index c435d7d4..b6662ff1 100755
--- a/config-db/slxconfig-demuxer
+++ b/config-db/slxconfig-demuxer
@@ -51,6 +51,7 @@ use OpenSLX::Basics;
use OpenSLX::ConfigDB qw(:support);
use OpenSLX::ConfigFolder;
use OpenSLX::MakeInitRamFS::Engine;
+use OpenSLX::OSPlugin::Roster;
use OpenSLX::ScopedResource;
use OpenSLX::Utils;
@@ -586,8 +587,24 @@ sub writePluginConfigurationsForSystem
# skip inactive plugins
next unless $attrs->{"${pluginName}::active"};
-
push @activePlugins, $pluginName;
+
+ my $plugin = OpenSLX::OSPlugin::Roster->getPlugin($pluginName);
+ my $requiredPlugins = $plugin->getInfo()->{required} || [];
+ my @missingPlugins
+ = grep {
+ my $required = $_;
+ ! grep {
+ $_->{plugin_name} eq $required
+ } @{$info->{'installed-plugins'}};
+ }
+ @$requiredPlugins;
+ if (@missingPlugins) {
+ die _tr(
+ 'the plugin "%s" requires the following plugins to be installed: "%s"!',
+ $pluginName, join(',', @missingPlugins)
+ );
+ }
next if $option{dryRun};
diff --git a/installer/OpenSLX/OSSetup/Engine.pm b/installer/OpenSLX/OSSetup/Engine.pm
index 66c03c85..31a3eb28 100644
--- a/installer/OpenSLX/OSSetup/Engine.pm
+++ b/installer/OpenSLX/OSSetup/Engine.pm
@@ -1699,7 +1699,7 @@ sub _installPlugins
}
return if ! @$plugins;
-
+
require OpenSLX::OSPlugin::Engine;
vlog(
0,
@@ -1707,7 +1707,11 @@ sub _installPlugins
? _tr("reinstalling plugins...\n")
: _tr("installing default plugins...\n")
);
- for my $pluginInfo (@$plugins) {
+ for my $pluginInfo (
+ sort {
+ $self->_sortPluginsByDependency($a->{plugin_name}, $b->{plugin_name});
+ } @$plugins
+ ) {
my $pluginName = $pluginInfo->{plugin_name};
my $pluginEngine = OpenSLX::OSPlugin::Engine->new();
vlog(0, _tr("\t%s\n", $pluginName));
@@ -1721,6 +1725,23 @@ sub _installPlugins
return;
}
+sub _sortPluginsByDependency
+{
+ my $self = shift;
+ my $pluginNameA = shift;
+ my $pluginNameB = shift;
+
+ my $pluginA = OpenSLX::OSPlugin::Roster->getPlugin($pluginNameA);
+ if ($pluginA->dependsOnPlugin($pluginNameB)) {
+ return 1;
+ }
+ my $pluginB = OpenSLX::OSPlugin::Roster->getPlugin($pluginNameB);
+ if ($pluginB->dependsOnPlugin($pluginNameA)) {
+ return -1;
+ }
+ return 0;
+}
+
################################################################################
### utility methods
################################################################################
diff --git a/os-plugins/OpenSLX/OSPlugin/Base.pm b/os-plugins/OpenSLX/OSPlugin/Base.pm
index 2b6075f5..734a74f5 100644
--- a/os-plugins/OpenSLX/OSPlugin/Base.pm
+++ b/os-plugins/OpenSLX/OSPlugin/Base.pm
@@ -61,6 +61,7 @@ implementation, please drop a mail to: ot@openslx.com, or join the IRC-channel
=cut
use OpenSLX::Basics;
+use OpenSLX::OSPlugin::Roster;
=head1 PLUGIN API
@@ -122,6 +123,13 @@ a higher precedence).
Valid values range from 0-99. If your plugin does not have any requirements
in this context, just specify the default value '50'.
+=item B<required>
+
+Specifies the list of plugins that are required by this plugin.
+
+Before any plugin can be installed, all other plugins that are required by it
+must have been installed.
+
=back
=cut
@@ -209,6 +217,23 @@ sub checkStage3AttrValues
return;
}
+=item dependsOnPlugin()
+
+=cut
+
+sub dependsOnPlugin
+{
+ my $self = shift;
+ my $otherName = shift;
+
+ if (!defined $self->{dependsOn}) {
+ my @dependsOn = $self->_determineAllPluginsWeDependOn();
+ $self->{dependsOn} = \@dependsOn;
+ }
+
+ return grep { $_ eq $otherName } @{$self->{dependsOn}};
+}
+
=back
=head2 Vendor-OS Interface
@@ -439,6 +464,28 @@ sub setupPluginInInitramfs
return 1;
}
+sub _determineAllPluginsWeDependOn
+{
+ my $self = shift;
+ my $seen = shift || {};
+
+ return if $seen->{$self->{name}};
+ $seen->{$self->{name}} = 1;
+
+ my %dependsOn;
+ if ($self->getInfo()->{required}) {
+ @dependsOn{@{$self->getInfo()->{required}}} = ();
+ }
+
+ foreach my $depName (keys %dependsOn) {
+ my $depPlugin = OpenSLX::OSPlugin::Roster->getPlugin($depName);
+ my @subDeps = $depPlugin->_determineAllPluginsWeDependOn($seen);
+ @dependsOn{@subDeps} = ();
+ }
+
+ return keys %dependsOn;
+}
+
=back
1;
diff --git a/os-plugins/OpenSLX/OSPlugin/Engine.pm b/os-plugins/OpenSLX/OSPlugin/Engine.pm
index 3f73a97a..ae76c9e0 100644
--- a/os-plugins/OpenSLX/OSPlugin/Engine.pm
+++ b/os-plugins/OpenSLX/OSPlugin/Engine.pm
@@ -23,6 +23,7 @@ use File::Path;
use Storable;
use OpenSLX::Basics;
+use OpenSLX::OSPlugin::Roster;
use OpenSLX::OSSetup::Engine;
use OpenSLX::ScopedResource;
use OpenSLX::Utils;
@@ -146,6 +147,8 @@ Invokes the plugin's installer method while chrooted into that vendor-OS.
sub installPlugin
{
my $self = shift;
+
+ $self->_checkIfRequiredPluginsAreInstalled();
if ($self->{'vendor-os-name'} ne '<<<default>>>') {
@@ -209,6 +212,8 @@ sub removePlugin
{
my $self = shift;
+ $self->_checkIfPluginIsRequiredByOthers();
+
if ($self->{'vendor-os-name'} ne '<<<default>>>') {
mkpath([ $self->{'plugin-repo-path'}, $self->{'plugin-temp-path'} ]);
@@ -638,6 +643,83 @@ sub _addInstalledPluginToDB
return 1;
}
+sub _checkIfRequiredPluginsAreInstalled
+{
+ my $self = shift;
+
+ my $requiredPlugins = $self->{plugin}->getInfo()->{required} || [];
+ return 1 if !@$requiredPlugins;
+
+ my $openslxDB = instantiateClass("OpenSLX::ConfigDB");
+ $openslxDB->connect();
+ my $vendorOS = $openslxDB->fetchVendorOSByFilter( {
+ name => $self->{'vendor-os-name'},
+ } );
+ if (!$vendorOS) {
+ die _tr(
+ 'unable to find vendor-OS "%s" in DB!', $self->{'vendor-os-name'}
+ );
+ }
+ my @installedPlugins = $openslxDB->fetchInstalledPlugins($vendorOS->{id});
+ $openslxDB->disconnect();
+
+ my @missingPlugins
+ = grep {
+ my $required = $_;
+ ! grep { $_->{plugin_name} eq $required } @installedPlugins;
+ }
+ @$requiredPlugins;
+
+ if (@missingPlugins) {
+ die _tr(
+ 'the plugin "%s" requires the following plugins to be installed first: "%s"!',
+ $self->{'plugin-name'}, join(',', @missingPlugins)
+ );
+ }
+
+ return 1;
+}
+
+sub _checkIfPluginIsRequiredByOthers
+{
+ my $self = shift;
+
+ my $openslxDB = instantiateClass("OpenSLX::ConfigDB");
+ $openslxDB->connect();
+ my $vendorOS = $openslxDB->fetchVendorOSByFilter( {
+ name => $self->{'vendor-os-name'},
+ } );
+ if (!$vendorOS) {
+ die _tr(
+ 'unable to find vendor-OS "%s" in DB!', $self->{'vendor-os-name'}
+ );
+ }
+ my @installedPlugins = $openslxDB->fetchInstalledPlugins($vendorOS->{id});
+ $openslxDB->disconnect();
+
+ my @lockingPlugins
+ = grep {
+ my $installed
+ = OpenSLX::OSPlugin::Roster->getPlugin($_->{plugin_name});
+ my $requiredByInstalled
+ = $installed
+ ? ($installed->getInfo()->{required} || [])
+ : [];
+ grep { $_ eq $self->{'plugin-name'} } @$requiredByInstalled;
+ }
+ @installedPlugins;
+
+ if (@lockingPlugins) {
+ die _tr(
+ 'the plugin "%s" is required by the following plugins: "%s"!',
+ $self->{'plugin-name'},
+ join(',', map { $_->{plugin_name} } @lockingPlugins)
+ );
+ }
+
+ return 1;
+}
+
sub _fetchInstalledPluginAttrs
{
my $self = shift;
diff --git a/os-plugins/plugins/vmchooser/OpenSLX/OSPlugin/vmchooser.pm b/os-plugins/plugins/vmchooser/OpenSLX/OSPlugin/vmchooser.pm
index 052a8694..8010dc24 100644
--- a/os-plugins/plugins/vmchooser/OpenSLX/OSPlugin/vmchooser.pm
+++ b/os-plugins/plugins/vmchooser/OpenSLX/OSPlugin/vmchooser.pm
@@ -42,6 +42,7 @@ sub getInfo
based on xml-files, which tell about available images.
End-of-Here
precedence => 50,
+ required => [ qw( vmware ) ],
};
}
diff --git a/os-plugins/slxos-plugin b/os-plugins/slxos-plugin
index 2b87e814..7d85bf68 100755
--- a/os-plugins/slxos-plugin
+++ b/os-plugins/slxos-plugin
@@ -109,7 +109,13 @@ if ($action =~ m[^list-at]i) {
my $fill = ' ' x 12;
chomp(my $descr = $pluginInfo->{$_}->{description} || '');
$descr =~ s{\n}{\n$fill}igms;
- "\n\t$_\n\t $descr\n";
+ my $pluginStr = "$_";
+ my $required = $pluginInfo->{$_}->{required} || [];
+ if (@$required) {
+ $pluginStr
+ .= _tr(' (requires: %s)', join(',', @$required));
+ }
+ "\n\t$pluginStr\n\t $descr\n";
}
else {
"\t$_\n";