From 431e6e2f2811dc277feaca90f52466d623a74b0b Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Fri, 14 Mar 2008 22:49:57 +0000 Subject: * added support for stage1 attributes that are stored along each plugin installed into a vendor-OS. * an update of the slxos-plugin documentation is still missing (coming soon ;-) git-svn-id: http://svn.openslx.org/svn/openslx/openslx/trunk@1633 95ad53e4-c205-0410-b2fa-d234c58c8868 --- config-db/OpenSLX/AttributeRoster.pm | 2 +- config-db/OpenSLX/ConfigDB.pm | 14 +- config-db/OpenSLX/DBSchema.pm | 31 +++- config-db/OpenSLX/MetaDB/DBI.pm | 74 +++++++-- installer/OpenSLX/OSSetup/Engine.pm | 7 +- os-plugins/OpenSLX/OSPlugin/Engine.pm | 50 +++++- os-plugins/OpenSLX/OSPlugin/Roster.pm | 8 +- .../plugins/vmware/OpenSLX/OSPlugin/vmware.pm | 18 ++- os-plugins/slxos-plugin | 169 +++++++++++++++------ 9 files changed, 295 insertions(+), 78 deletions(-) diff --git a/config-db/OpenSLX/AttributeRoster.pm b/config-db/OpenSLX/AttributeRoster.pm index b3366c01..5549af3f 100644 --- a/config-db/OpenSLX/AttributeRoster.pm +++ b/config-db/OpenSLX/AttributeRoster.pm @@ -369,7 +369,7 @@ sub _init ); # and add all plugin attributes, too - OpenSLX::OSPlugin::Roster->addAllDefaultAttributesToHash(\%AttributeInfo); + OpenSLX::OSPlugin::Roster->addAllStage3AttributesToHash(\%AttributeInfo); } =item C diff --git a/config-db/OpenSLX/ConfigDB.pm b/config-db/OpenSLX/ConfigDB.pm index 9d876880..4b13c3f5 100644 --- a/config-db/OpenSLX/ConfigDB.pm +++ b/config-db/OpenSLX/ConfigDB.pm @@ -385,9 +385,6 @@ sub fetchInstalledPlugins my $vendorOSID = shift; my $pluginName = shift; - return map { - $_->{plugin_name} - } $self->{'meta-db'}->fetchInstalledPlugins($vendorOSID, $pluginName); } @@ -1096,14 +1093,17 @@ The ID of the new reference entry, C if the creation failed. sub addInstalledPlugin { - my $self = shift; - my $vendorOSID = shift; - my $pluginName = shift; + my $self = shift; + my $vendorOSID = shift; + my $pluginName = shift; + my $pluginAttrs = shift || {}; # make sure the attributes of this plugin are available via default system $self->{'db-schema'}->synchronizeAttributesWithDefaultSystem($self); - return $self->{'meta-db'}->addInstalledPlugin($vendorOSID, $pluginName); + return $self->{'meta-db'}->addInstalledPlugin( + $vendorOSID, $pluginName, $pluginAttrs + ); } =item C diff --git a/config-db/OpenSLX/DBSchema.pm b/config-db/OpenSLX/DBSchema.pm index 63774dfb..2be6dc7c 100644 --- a/config-db/OpenSLX/DBSchema.pm +++ b/config-db/OpenSLX/DBSchema.pm @@ -35,7 +35,7 @@ use OpenSLX::Basics; ### fk => foreign key (integer) ################################################################################ -my $VERSION = 0.28; +my $VERSION = 0.29; my $DbSchema = { 'version' => $VERSION, @@ -162,6 +162,15 @@ my $DbSchema = { # corresponding stage1, too. ], }, + 'installed_plugin_attr' => { + # (stage1-)attributes of installed plugins + 'cols' => [ + 'id:pk', # primary key + 'installed_plugin_id:fk', # foreign key to installed plugin + 'name:s.128', # attribute name + 'value:s.255', # attribute value + ], + }, 'meta' => { # information about the database as such 'cols' => [ @@ -567,7 +576,7 @@ sub _schemaUpgradeDBFrom 0.21 => sub { my $metaDB = shift; - # add new table installed_plugins + # add new table installed_plugin $metaDB->schemaAddTable( 'installed_plugin', [ @@ -590,7 +599,7 @@ sub _schemaUpgradeDBFrom 0.23 => sub { my $metaDB = shift; - # add new column system.descripion + # add new column system.description $metaDB->schemaAddColumns( 'system', [ @@ -693,6 +702,22 @@ sub _schemaUpgradeDBFrom # the default plugins here: $metaDB->addInstalledPlugin(0, 'theme'); + return 1; + }, + 0.29 => sub { + my $metaDB = shift; + + # add new table installed_plugin_attrs + $metaDB->schemaAddTable( + 'installed_plugin_attr', + [ + 'id:pk', + 'installed_plugin_id:fk', + 'name:s.128', + 'value:s.255', + ], + ); + return 1; }, ); diff --git a/config-db/OpenSLX/MetaDB/DBI.pm b/config-db/OpenSLX/MetaDB/DBI.pm index 746c407e..50c1465d 100644 --- a/config-db/OpenSLX/MetaDB/DBI.pm +++ b/config-db/OpenSLX/MetaDB/DBI.pm @@ -206,6 +206,7 @@ sub fetchInstalledPlugins my $self = shift; my $vendorOSID = shift; my $pluginName = shift; + my $fullInfo = shift || 0; return if !defined $vendorOSID; my $nameClause @@ -217,7 +218,26 @@ sub fetchInstalledPlugins WHERE vendor_os_id = '$vendorOSID' $nameClause End-of-Here - return $self->_doSelect($sql); + my @pluginInfos = $self->_doSelect($sql); + return if !@pluginInfos; + + @pluginInfos = map { + my $pluginInfo = $_; + my $sql = unshiftHereDoc(<<" End-of-Here"); + SELECT * FROM installed_plugin_attr + WHERE installed_plugin_id = '$pluginInfo->{id}' + End-of-Here + my @attrs = $self->_doSelect($sql); + $pluginInfo->{attrs} = { + map { + ( $_->{name}, $fullInfo ? $_ : $_->{value} ) + } @attrs + }; + $pluginInfo; + } + @pluginInfos; + + return wantarray() ? @pluginInfos : $pluginInfos[0]; } sub fetchExportByFilter @@ -703,17 +723,50 @@ sub changeVendorOS sub addInstalledPlugin { - my $self = shift; - my $vendorOSID = shift; - my $pluginName = shift; + my $self = shift; + my $vendorOSID = shift; + my $pluginName = shift; + my $pluginAttrs = shift; return if !defined $vendorOSID || !$pluginName; - return if $self->fetchInstalledPlugins($vendorOSID, $pluginName); - return $self->_doInsert('installed_plugin', [ { - vendor_os_id => $vendorOSID, - plugin_name => $pluginName, - } ] ); + my $installedPlugin + = $self->fetchInstalledPlugins($vendorOSID, $pluginName, 1); + if (!$installedPlugin) { + return if !$self->_doInsert('installed_plugin', [ { + vendor_os_id => $vendorOSID, + plugin_name => $pluginName, + } ] ); + $installedPlugin + = $self->fetchInstalledPlugins($vendorOSID, $pluginName, 1); + } + return if !$installedPlugin; + for my $pluginAttrName (keys %$pluginAttrs) { + if (exists $installedPlugin->{attrs}->{$pluginAttrName}) { + my $attrInfo = $installedPlugin->{attrs}->{$pluginAttrName}; + my $currVal + = defined $attrInfo->{value} ? $attrInfo->{value} : '-'; + my $givenVal + = defined $pluginAttrs->{$pluginAttrName} + ? $pluginAttrs->{$pluginAttrName} + : '-'; +print "$pluginAttrName: $currVal <=> $givenVal\n"; + next if $currVal eq $givenVal; + return if ! $self->_doUpdate( + 'installed_plugin_attr', [ $attrInfo->{id} ], [ { + value => $pluginAttrs->{$pluginAttrName}, + } ] + ); + } + else { + return if ! $self->_doInsert('installed_plugin_attr', [ { + installed_plugin_id => $installedPlugin->{id}, + name => $pluginAttrName, + value => $pluginAttrs->{$pluginAttrName}, + } ] ); + } + } + return 1; } sub removeInstalledPlugin @@ -726,6 +779,9 @@ sub removeInstalledPlugin my $plugin = $self->fetchInstalledPlugins($vendorOSID, $pluginName); return if !$plugin; + return if !$self->_doDelete( + 'installed_plugin_attr', [ $plugin->{id} ], 'installed_plugin_id' + ); return $self->_doDelete('installed_plugin', [ $plugin->{id} ] ); } diff --git a/installer/OpenSLX/OSSetup/Engine.pm b/installer/OpenSLX/OSSetup/Engine.pm index e539e8e3..e4b07260 100644 --- a/installer/OpenSLX/OSSetup/Engine.pm +++ b/installer/OpenSLX/OSSetup/Engine.pm @@ -1716,10 +1716,13 @@ sub _installPlugins ? _tr("reinstalling plugins...\n") : _tr("installing default plugins...\n") ); - for my $pluginName (@$plugins) { + for my $pluginInfo (@$plugins) { + my $pluginName = $pluginInfo->{name}; my $pluginEngine = OpenSLX::OSPlugin::Engine->new(); vlog(0, _tr("\t%s\n", $pluginName)); - $pluginEngine->initialize($pluginName, $self->{'vendor-os-name'}); + $pluginEngine->initialize( + $pluginName, $self->{'vendor-os-name'}, $pluginInfo->{attrs} + ); $pluginEngine->installPlugin(); } vlog(0, _tr("done with plugins.\n")); diff --git a/os-plugins/OpenSLX/OSPlugin/Engine.pm b/os-plugins/OpenSLX/OSPlugin/Engine.pm index 23d3d953..d42141a7 100644 --- a/os-plugins/OpenSLX/OSPlugin/Engine.pm +++ b/os-plugins/OpenSLX/OSPlugin/Engine.pm @@ -67,6 +67,7 @@ sub initialize my $self = shift; my $pluginName = shift; my $vendorOSName = shift; + my $givenAttrs = shift || {}; $self->{'vendor-os-name'} = $vendorOSName; @@ -92,6 +93,27 @@ sub initialize $self->{'plugin-temp-path'} = "$self->{'vendor-os-path'}/$self->{'chrooted-plugin-temp-path'}"; $self->{'chrooted-openslx-base-path'} = '/mnt/openslx'; + + # check and store given attribute set + my $knownAttrs = $self->{plugin}->getAttrInfo(); + my @unknownAttrs + = grep { !exists $knownAttrs->{$_} } keys %$givenAttrs; + if (@unknownAttrs) { + die _tr( + "The plugin '%s' does not support these attributes:\n\t%s", + $pluginName, join(',', @unknownAttrs) + ); + } + $self->{'plugin-attrs'} = $givenAttrs; + my $defaultAttrs = $self->{plugin}->getAttrInfo(); + my $dbAttrs = $self->_fetchInstalledPluginAttrs($vendorOSName); + for my $attrName (keys %$defaultAttrs) { + next if exists $givenAttrs->{$attrName}; + $self->{'plugin-attrs'}->{$attrName} + = exists $dbAttrs->{$attrName} + ? $dbAttrs->{$attrName} + : $defaultAttrs->{$attrName}->{default}; + } } return 1; @@ -124,6 +146,7 @@ sub installPlugin $self->{'chrooted-plugin-repo-path'}, $self->{'chrooted-plugin-temp-path'}, $self->{'chrooted-openslx-base-path'}, + $self->{'plugin-attrs'}, ); } ); @@ -426,12 +449,37 @@ sub _addInstalledPluginToDB 'unable to find vendor-OS "%s" in DB!', $self->{'vendor-os-name'} ); } - $openslxDB->addInstalledPlugin($vendorOS->{id}, $self->{'plugin-name'}); + $openslxDB->addInstalledPlugin( + $vendorOS->{id}, $self->{'plugin-name'}, $self->{'plugin-attrs'} + ); $openslxDB->disconnect(); return 1; } +sub _fetchInstalledPluginAttrs +{ + 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 $installedPlugin = $openslxDB->fetchInstalledPlugins( + $vendorOS->{id}, $self->{'plugin-name'} + ); + $openslxDB->disconnect(); + + return {} if !$installedPlugin; + return $installedPlugin->{attrs}; +} + sub _removeInstalledPluginFromDB { my $self = shift; diff --git a/os-plugins/OpenSLX/OSPlugin/Roster.pm b/os-plugins/OpenSLX/OSPlugin/Roster.pm index 8bc2c305..bacbd183 100644 --- a/os-plugins/OpenSLX/OSPlugin/Roster.pm +++ b/os-plugins/OpenSLX/OSPlugin/Roster.pm @@ -78,10 +78,10 @@ sub getPluginAttrInfo return $plugins{$pluginName}->getAttrInfo(); } -=item C +=item C -Fetches attribute info from all available plugins and adds it to the given -hash-ref. +Fetches attribute info relevant for stage3 (i.e. system- or client-attributes) +from all available plugins and adds it to the given hash-ref. =over @@ -93,7 +93,7 @@ hash-ref. =cut -sub addAllDefaultAttributesToHash +sub addAllStage3AttributesToHash { my $class = shift; my $attrInfo = shift; diff --git a/os-plugins/plugins/vmware/OpenSLX/OSPlugin/vmware.pm b/os-plugins/plugins/vmware/OpenSLX/OSPlugin/vmware.pm index af4df603..7a9a57cb 100644 --- a/os-plugins/plugins/vmware/OpenSLX/OSPlugin/vmware.pm +++ b/os-plugins/plugins/vmware/OpenSLX/OSPlugin/vmware.pm @@ -75,7 +75,7 @@ sub getAttrInfo End-of-Here content_regex => qr{^\d\d$}, content_descr => 'allowed range is from 01-99', - default => 70, + default => '70', }, # attribute 'imagesrc' defines where we can find vmware images 'vmware::imagessrc' => { @@ -84,9 +84,21 @@ sub getAttrInfo description => unshiftHereDoc(<<' End-of-Here'), Where do we store our vmware images? NFS? Filesystem? End-of-Here - content_regex => qr{^\d\d$}, content_descr => 'Allowed values: path or URI', - default => "", + default => '', + }, + # attribute 'binaries' defines whether or not VMware binaries shall + # be provided (by downloading them). + 'vmware::binaries' => { + applies_to_vendor_os => 1, + applies_to_systems => 0, + applies_to_clients => 0, + description => unshiftHereDoc(<<' End-of-Here'), + Shall VMware binaries be downloaded and installed? + End-of-Here + content_regex => qr{^(0|1)$}, + content_descr => 'Allowed values: 0 or 1', + default => '1', }, }; diff --git a/os-plugins/slxos-plugin b/os-plugins/slxos-plugin index 8400ecf7..db7767a0 100755 --- a/os-plugins/slxos-plugin +++ b/os-plugins/slxos-plugin @@ -60,8 +60,6 @@ openslxInit(); my $action = shift @ARGV || ''; if ($action =~ m[^list-a]i) { - my @pluginFolders - = grep { -d $_ } glob("$openslxConfig{'base-path'}/lib/plugins/*"); print _tr("List of available plugins:\n"); require OpenSLX::OSPlugin::Roster; my $pluginInfo = OpenSLX::OSPlugin::Roster->getAvailablePlugins(); @@ -104,77 +102,117 @@ if ($action =~ m[^list-a]i) { my $engine = OpenSLX::OSPlugin::Engine->new; $engine->initialize(undef, $vendorOSName); my @installedPlugins = $engine->getInstalledPlugins(); + if (!@installedPlugins) { - push @installedPlugins, ''; + push @installedPlugins, { plugin_name => '' }; } print _tr("List of plugins installed in vendor-OS '$vendorOSName':\n"); - print join('', map { "\t$_\n" } sort @installedPlugins); + print join( + '', + map { + if ($option{verbose}) { + my $attributes + = _tr("The following attributes were applied:") + . "\n\t "; + my $pluginAttrs = $_->{attrs}; + $attributes .= join( + "\n\t ", + map { + $_ . '=' + . ( + defined $pluginAttrs->{$_} + ? $pluginAttrs->{$_} + : '-' + ) + } + sort keys %$pluginAttrs + ); + "\n\t$_->{plugin_name}\n\t $attributes\n"; + } + else { + "\t$_->{plugin_name}\n"; + } + } + sort @installedPlugins + ); } elsif ($action =~ m[^install]i) { - if (scalar(@ARGV) != 2) { + if (scalar(@ARGV) < 2) { print STDERR _tr( - "You need to specify exactly one plugin-name and one vendor-OS!\n" + "You need to specify a vendor-OS and at least one plugin-name!\n" ); pod2usage(2); } - my $pluginName = shift @ARGV; my $vendorOSName = shift @ARGV; + my $pluginAttrs = parsePluginAttrs(1); # we chdir into the script's folder such that all relative paths have # a known starting point: chdir($FindBin::RealBin) or die _tr("can't chdir to script-path <%> (%s)", $FindBin::RealBin, $!); - # create OSPlugin-engine for given plugin and vendor-OS and start it: - my $engine = OpenSLX::OSPlugin::Engine->new; - $engine->initialize($pluginName, $vendorOSName); - if (!-e $engine->{'plugin-path'}) { - die _tr("plugin '%s' doesn't exist, giving up!\n", - $engine->{'plugin-path'}); - } - if ($vendorOSName ne '<<>>' && !-e $engine->{'vendor-os-path'}) { - die _tr("vendor-OS '%s' doesn't exist, giving up!\n", - $engine->{'vendor-os-path'}); - } - if ($engine->installPlugin()) { - print _tr( - "Plugin $pluginName has been installed into vendor-OS '$vendorOSName'.\n" + for my $pluginName (keys %$pluginAttrs) { + # create & start OSPlugin-engine for vendor-OS and current plugin: + my $engine = OpenSLX::OSPlugin::Engine->new; + $engine->initialize( + $pluginName, $vendorOSName, $pluginAttrs->{$pluginName} ); + if (!-e $engine->{'plugin-path'}) { + die _tr("plugin '%s' doesn't exist, giving up!\n", + $engine->{'plugin-path'}); + } + if ($vendorOSName ne '<<>>' + && !-e $engine->{'vendor-os-path'}) { + die _tr( + "vendor-OS '%s' doesn't exist, giving up!\n", + $engine->{'vendor-os-path'} + ); + } + if ($engine->installPlugin()) { + print _tr( + "Plugin $pluginName has been installed into vendor-OS '$vendorOSName'.\n" + ); + } } } elsif ($action =~ m[^remove]i) { - if (scalar(@ARGV) != 2) { + if (scalar(@ARGV) < 2) { print STDERR _tr( - "You need to specify exactly one plugin-name and one vendor-OS!\n" + "You need to specify a vendor-OS and at least one plugin-name!\n" ); pod2usage(2); } - my $pluginName = shift @ARGV; my $vendorOSName = shift @ARGV; + my $pluginAttrs = parsePluginAttrs(0); # we chdir into the script's folder such that all relative paths have # a known starting point: chdir($FindBin::RealBin) or die _tr("can't chdir to script-path <%> (%s)", $FindBin::RealBin, $!); - # create OSPlugin-engine for given plugin and vendor-OS and start it: - my $engine = OpenSLX::OSPlugin::Engine->new; - $engine->initialize($pluginName, $vendorOSName); - if (!-e $engine->{'plugin-path'}) { - die _tr("plugin '%s' doesn't exist, giving up!\n", - $engine->{'plugin-path'}); - } - if ($vendorOSName ne '<<>>' && !-e $engine->{'vendor-os-path'}) { - die _tr("vendor-OS '%s' doesn't exist, giving up!\n", - $engine->{'vendor-os-path'}); - } - if ($engine->removePlugin()) { - print _tr( - "Plugin $pluginName has been removed from vendor-OS '$vendorOSName'.\n" + for my $pluginName (keys %$pluginAttrs) { + # create & start OSPlugin-engine for vendor-OS and current plugin: + my $engine = OpenSLX::OSPlugin::Engine->new; + $engine->initialize( + $pluginName, $vendorOSName, $pluginAttrs->{$pluginName} ); + if (!-e $engine->{'plugin-path'}) { + die _tr("plugin '%s' doesn't exist, giving up!\n", + $engine->{'plugin-path'}); + } + if ($vendorOSName ne '<<>>' && !-e $engine->{'vendor-os-path'}) { + die _tr("vendor-OS '%s' doesn't exist, giving up!\n", + $engine->{'vendor-os-path'}); + } + if ($engine->removePlugin()) { + print _tr( + "Plugin $pluginName has been removed from vendor-OS '$vendorOSName'.\n" + ); + } } } else { vlog(0, _tr(unshiftHereDoc(<<' END-OF-HERE'), $0)); You need to specify exactly one action: install + list-attributes list-available list-installed remove @@ -182,6 +220,38 @@ if ($action =~ m[^list-a]i) { END-OF-HERE } +sub parsePluginAttrs +{ + my $acceptAttributes = shift; + + my (%pluginAttrs, $pluginName, @attrSpecs); + for my $arg (@ARGV) { + if ($arg =~ m{^(.+)=(.*)$}) { + next if !$acceptAttributes; + my $attr = $1; + my $value = $2; + if ($value =~ m{^(-|undef)$}) { + $value = undef; + } + if ($attr =~ m{^(.+)::}) { + $pluginName = $1; + } + else { + if (!defined $pluginName) { + die _tr('You have to give a plugin-name before you can specify unscoped attributes!'); + } + $attr = $pluginName . '::' . $attr; + } + $pluginAttrs{$pluginName}->{$attr} = $value; + } + else { + $pluginName = $arg; + $pluginAttrs{$pluginName} = {}; + } + } + return \%pluginAttrs; +} + =head1 NAME slxos-plugin - OpenSLX-script to install/remove an OS-plugin into/from an @@ -202,21 +272,24 @@ slxos-plugin [options] =over 8 -=item B<< install >> +=item B<< install [= ...] [] ... >> -installs the OS-plugin with the given name into the specified vendor-OS +installs the OS-plugin(s) with the given name(s) into the specified +vendor-OS, using any attribute values as specified =item B<< list-available >> -list all available OS-plugins +list all available OS-plugins, in verbose mode all the supported attributes +are shown, too. =item B<< list-installed >> -list all the plugins installed into the specified vendor-OS +list all the plugins installed into the specified vendor-OS, in verbose mode +all applied attributes are shown, too. -=item B<< remove >> +=item B<< remove [] ... >> -removes the OS-plugin with the given name from the specified vendor-OS +removes the OS-plugin(s) with the given name(s) from the specified vendor-OS =back @@ -261,9 +334,9 @@ Prints the version and exits. =head3 Installing a Plugin -=item B<< slxos-plugin install Example suse-10.2 >> +=item B<< slxos-plugin install suse-10.2 example >> -installs the plugin named 'Example' into the installed vendor-OS 'suse-10.2'. +installs the plugin named 'example' into the installed vendor-OS 'suse-10.2'. =back @@ -271,9 +344,9 @@ installs the plugin named 'Example' into the installed vendor-OS 'suse-10.2'. =over 8 -=item B<< slxos-plugin remove Example suse-10.2 >> +=item B<< slxos-plugin remove suse-10.2 example >> -removes the plugin named 'Example' from the installed vendor-OS 'suse-10.2'. +removes the plugin named 'example' from the installed vendor-OS 'suse-10.2'. =back -- cgit v1.2.3-55-g7522