From a6b29cc972d8775398b4ae03d69123af3034a4ee Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Thu, 3 Jan 2008 15:20:44 +0000 Subject: * intermediate checkin of refactoring of the way attributes are stored in DB and passed in and out via the DB-layer N.B.: this may break things, will be fixed later today git-svn-id: http://svn.openslx.org/svn/openslx/trunk@1440 95ad53e4-c205-0410-b2fa-d234c58c8868 --- config-db/OpenSLX/AttrInfo/Core.pm | 348 ++++++++++++++++++++ config-db/OpenSLX/ConfigDB.pm | 106 +++++- config-db/OpenSLX/DBSchema.pm | 649 +++++++++++++++++++++++-------------- config-db/OpenSLX/MetaDB/Base.pm | 12 +- config-db/OpenSLX/MetaDB/DBI.pm | 125 +++++-- 5 files changed, 948 insertions(+), 292 deletions(-) create mode 100644 config-db/OpenSLX/AttrInfo/Core.pm (limited to 'config-db') diff --git a/config-db/OpenSLX/AttrInfo/Core.pm b/config-db/OpenSLX/AttrInfo/Core.pm new file mode 100644 index 00000000..a1c06019 --- /dev/null +++ b/config-db/OpenSLX/AttrInfo/Core.pm @@ -0,0 +1,348 @@ +# 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/ +# ----------------------------------------------------------------------------- +# AttrInfo::Core +# - provides info about the core attributes. +# ----------------------------------------------------------------------------- +package OpenSLX::AttrInfo::Core; + +use strict; +use warnings; + +use OpenSLX::Utils; + +use vars qw(@ISA @EXPORT $VERSION %AttrInfo); + +use Exporter; +$VERSION = 1.01; +@ISA = qw(Exporter); + +@EXPORT = qw( %AttrInfo ); + +%AttrInfo = ( + 'automnt_dir' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'automnt_src' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'country' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'dm_allow_shutdown' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'hw_graphic' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'hw_monitor' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'hw_mouse' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'late_dm' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'netbios_workgroup' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'nis_domain' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'nis_servers' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'sane_scanner' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'scratch' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'slxgrp' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_alsasound' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_atd' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_cron' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_dreshal' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_ntp' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_nfsv4' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_printer' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_samba' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_snmp' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_sshd' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_syslogd' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_x' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'start_xdmcp' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'tex_enable' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'timezone' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + textual timezone (e.g. 'Europe/Berlin') + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'tvout' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'vmware' => { + applies_to_systems => 1, + applies_to_clients => 1, + description => unshiftHereDoc(<<' End-of-Here'), + !!!descriptive text missing here!!! + End-of-Here + content_regex => undef, + content_descr => undef, + }, + + 'ramfs_fsmods' => { + applies_to_systems => 1, + applies_to_clients => 0, + description => unshiftHereDoc(<<' End-of-Here'), + list of filesystem kernel modules to load + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'ramfs_miscmods' => { + applies_to_systems => 1, + applies_to_clients => 0, + description => unshiftHereDoc(<<' End-of-Here'), + list of miscellaneous kernel modules to load + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'ramfs_nicmods' => { + applies_to_systems => 1, + applies_to_clients => 0, + description => unshiftHereDoc(<<' End-of-Here'), + list of network card modules to load + End-of-Here + content_regex => undef, + content_descr => undef, + }, + 'ramfs_screen' => { + applies_to_systems => 1, + applies_to_clients => 0, + description => unshiftHereDoc(<<' End-of-Here'), + resolution of splash screen to use in stage3 + End-of-Here + content_regex => undef, + content_descr => undef, + }, +); + +1; diff --git a/config-db/OpenSLX/ConfigDB.pm b/config-db/OpenSLX/ConfigDB.pm index 9b6218cb..debbef9c 100644 --- a/config-db/OpenSLX/ConfigDB.pm +++ b/config-db/OpenSLX/ConfigDB.pm @@ -183,11 +183,8 @@ sub connect ## no critic (ProhibitBuiltinHomonyms) $self->{'db-type'} = $dbType; $self->{'meta-db'} = $metaDB; - foreach my $tk (keys %{$DbSchema->{tables}}) { - $metaDB->schemaDeclareTable($tk, $DbSchema->{tables}->{$tk}); - } - _checkAndUpgradeDBSchemaIfNecessary($metaDB); + $self->_checkAndUpgradeDBSchemaIfNecessary($metaDB); return 1; } @@ -286,7 +283,9 @@ sub getColumnsOfTable my $self = shift; my $tableName = shift; - return map { (/^(\w+)\W/) ? $1 : $_; } @{$DbSchema->{tables}->{$tableName}}; + return + map { (/^(\w+)\W/) ? $1 : $_; } + @{$DbSchema->{tables}->{$tableName}->{cols}}; } =item C @@ -510,6 +509,17 @@ sub fetchSystemByFilter my @systems = $self->{'meta-db'}->fetchSystemByFilter($filter, $resultCols); + # unless specific result cols have been given, we mix in the attributes + # of each system, too: + if (!defined $resultCols) { + foreach my $system (@systems) { + my @attrs = $self->{'meta-db'}->fetchSystemAttrs($system->{id}); + foreach my $attr (@attrs) { + $system->{"attr_$attr->{name}"} = $attr->{value}; + } + } + } + return wantarray() ? @systems : shift @systems; } @@ -542,6 +552,17 @@ sub fetchSystemByID my $resultCols = shift; my @systems = $self->{'meta-db'}->fetchSystemByID($ids, $resultCols); + + # unless specific result cols have been given, we mix in the attributes + # of each system, too: + if (!defined $resultCols) { + foreach my $system (@systems) { + my @attrs = $self->{'meta-db'}->fetchSystemAttrs($system->{id}); + foreach my $attr (@attrs) { + $system->{"attr_$attr->{name}"} = $attr->{value}; + } + } + } return wantarray() ? @systems : shift @systems; } @@ -1217,6 +1238,43 @@ sub changeSystem return $self->{'meta-db'}->changeSystem($systemIDs, $valRows); } +=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. @@ -2621,22 +2679,38 @@ sub generatePlaceholderFor ################################################################################ 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, as 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: + # 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 < $DbSchema->{version}) { - vlog(1, - _tr('Our schema-version is %s, DB is %s, upgrading DB...', - $DbSchema->{version}, $currVersion)); + 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} + ); + } + 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 + ) + ); foreach my $v (sort { $a <=> $b } keys %DbSchemaHistory) { next if $v <= $currVersion; my $changeSet = $DbSchemaHistory{$v}; @@ -2676,6 +2750,10 @@ sub _checkAndUpgradeDBSchemaIfNecessary $changeDescr->{'col-renames'}, $changeDescr->{'cols'} ); + } elsif ($cmd eq 'perl-func') { + if (!$changeDescr->{code}->($self)) { + croak _tr('problem in perl-func cmd!'); + } } else { croak _tr('UnknownDbSchemaCommand', $cmd); } @@ -2683,7 +2761,7 @@ sub _checkAndUpgradeDBSchemaIfNecessary } vlog(1, _tr('upgrade done')); } else { - vlog(1, _tr('DB matches current schema version %s', $currVersion)); + vlog(1, _tr('DB matches current schema version (%s)', $currVersion)); } return 1; diff --git a/config-db/OpenSLX/DBSchema.pm b/config-db/OpenSLX/DBSchema.pm index 6600edca..9b692b59 100644 --- a/config-db/OpenSLX/DBSchema.pm +++ b/config-db/OpenSLX/DBSchema.pm @@ -19,7 +19,7 @@ use warnings; our (@ISA, @EXPORT, $VERSION); use Exporter; -$VERSION = 0.01; +$VERSION = 0.2; @ISA = qw(Exporter); @EXPORT = qw( @@ -28,49 +28,21 @@ $VERSION = 0.01; our ($DbSchema, %DbSchemaHistory); -# configurable attributes for system, client and group: -my @sharedAttributes = ( - 'attr_automnt_dir:s.128', - 'attr_automnt_src:s.128', -# 'attr_auth_type:s.64', - # not used currently! - 'attr_country:s.64', - 'attr_dm_allow_shutdown:s.16', -# 'attr_home_type:s.64', - # not used currently! - 'attr_hw_graphic:s.64', - 'attr_hw_monitor:s.64', - 'attr_hw_mouse:s.64', - 'attr_late_dm:s.16', - 'attr_netbios_workgroup:s.64', - 'attr_nis_domain:s.64', - 'attr_nis_servers:s.64', - 'attr_sane_scanner:s.64', - 'attr_scratch:s.128', - 'attr_slxgrp:s.64', - 'attr_start_alsasound:s.16', - 'attr_start_atd:s.16', - 'attr_start_cron:s.16', - 'attr_start_dreshal:s.16', - 'attr_start_ntp:s.16', - 'attr_start_nfsv4:s.16', - 'attr_start_printer:s.16', - 'attr_start_samba:s.16', - 'attr_start_snmp:s.16', - 'attr_start_sshd:s.16', - 'attr_start_syslog:s.64', - 'attr_start_x:s.32', - 'attr_start_xdmcp:s.32', - 'attr_tex_enable:s.16', - 'attr_timezone:s.32', - 'attr_tvout:s.32', - 'attr_vmware:s.128', -); +use POSIX qw(locale_h); +my $lang = setlocale(LC_MESSAGES); +my $country; +if ($lang =~ m[^\w\w_(\w\w)]) { + $country = lc($1); +} else { + $country = 'us'; +} ################################################################################ ### DB-schema definition -### This hash-ref describes the current OpenSLX configuration database schema. -### Each table is defined by a list of column descriptions. +### This hash-ref describes the current OpenSLX configuration database +### schema. +### Each table is defined by a list of column descriptions (and optionally +### a list of default values). ### A column description is simply the name of the column followed by ':' ### followed by the data type description. The following data types are ### currently supported: @@ -84,266 +56,463 @@ my @sharedAttributes = ( $DbSchema = { 'version' => $VERSION, 'tables' => { - 'meta' => [ - # information about the database as such - 'schema_version:s.5', # schema-version currently implemented by DB - ], - 'vendor_os' => [ - # a vendor-OS describes a folder containing an operating system as - # provided by the vendor (a.k.a. unchanged and thus updatable) - 'id:pk', # primary key - 'name:s.48', # structured name of OS installation - # (e.g. suse-9.3-kde, debian-3.1-ppc, - # suse-10.2-cloned-from-kiwi). - # This is used as the folder name for the - # corresponding stage1, too. - 'comment:s.1024', # internal comment (optional, for admins) - 'clone_source:s.256', # if vendor-OS was cloned, this contains - # the rsync-URI pointing to the original - ], - 'export' => [ + 'client' => { + # a client is a PC booting via network + 'cols' => [ + 'id:pk', # primary key + 'name:s.128', # official name of PC (e.g. as given by sticker + # on case) + 'mac:s.20', # MAC of NIC used for booting + 'boot_type:s.20', # type of remote boot procedure (PXE, ...) + 'unbootable:b', # unbootable clients simply won't boot + 'kernel_params:s.128', # client-specific kernel-args (e.g. console) + 'comment:s.1024', # internal comment (optional, for admins) + ], + 'vals' => [ + { # add default client + 'id' => 0, + 'name' => '<<>>', + 'comment' => 'internal client that holds default values', + }, + ], + }, + 'client_system_ref' => { + # clients referring to the systems they should offer for booting + 'cols' => [ + 'client_id:fk', # foreign key + 'system_id:fk', # foreign key + ], + }, + 'export' => { # an export describes a vendor-OS "wrapped" in some kind of exporting # format (NFS or NBD-squash). This represents the rootfs that the # clients will see. - 'id:pk', # primary key - 'name:s.64', # unique name of export, is automatically + 'cols' => [ + 'id:pk', # primary key + 'name:s.64', # unique name of export, is automatically # constructed like this: # - - 'vendor_os_id:fk', # foreign key - 'comment:s.1024', # internal comment (optional, for admins) - 'type:s.10', # 'nbd', 'nfs', ... - 'server_ip:s.16', # IP of exporting server, if empty the + 'vendor_os_id:fk', # foreign key + 'comment:s.1024', # internal comment (optional, for admins) + 'type:s.10', # 'nbd', 'nfs', ... + 'server_ip:s.16', # IP of exporting server, if empty the # boot server will be used - 'port:i', # some export types need to use a specific + 'port:i', # some export types need to use a specific # port for each incarnation, if that's the # case you can specify it here - 'uri:s.256', # path to export (squashfs or NFS-path), if + 'uri:s.255', # path to export (squashfs or NFS-path), if # empty it will be auto-generated by # config-demuxer - ], - 'system' => [ - # a system describes one bootable instance of an export, it - # represents a selectable line in the PXE boot menu of all the - # clients associated with this system - 'id:pk', # primary key - 'export_id:fk', # foreign key - 'name:s.64', # unique name of system, is automatically - # constructed like this: - # -- - 'label:s.64', # name visible to user (pxe-label) - # if empty, this will be autocreated from - # the name - 'comment:s.1024', # internal comment (optional, for admins) - 'kernel:s.128', # path to kernel file, relative to /boot - 'kernel_params:s.512', # kernel-param string for pxe - 'attr_ramfs_nicmods:s.256', # list of network interface card modules - 'attr_ramfs_fsmods:s.256', # list of filesystem modules - 'attr_ramfs_miscmods:s.256', # list of miscellaneous modules - 'attr_ramfs_screen:s.10', # screen size for splash - 'hidden:b', # hidden systems won't be offered for booting - @sharedAttributes, - ], - 'client' => [ - # a client is a PC booting via network - 'id:pk', # primary key - 'name:s.128', # official name of PC (e.g. as given by sticker - # on case) - 'mac:s.20', # MAC of NIC used for booting - 'comment:s.1024', # internal comment (optional, for admins) - 'boot_type:s.20', # type of remote boot procedure (PXE, ...) - 'unbootable:b', # unbootable clients simply won't boot - 'kernel_params:s.128', # client-specific kernel-args (e.g. console) - @sharedAttributes, - ], - 'client_system_ref' => [ - # clients referring to the systems they should offer for booting - 'client_id:fk', # foreign key - 'system_id:fk', # foreign key - ], - 'groups' => [ + ], + }, + 'global_info' => { + # a home for global counters and other info + 'cols' => [ + 'id:s.32', # key + 'value:s.128', # value + ], + 'vals' => [ + { # add nbd-server-port + 'id' => 'next-nbd-server-port', + 'value' => '5000', + }, + ], + }, + 'groups' => { # a group encapsulates a set of clients as one entity, managing # a group-specific attribute set. All the different attribute # sets a client inherits via group membership are folded into # one resulting attribute set with respect to each group's priority. - 'id:pk', # primary key - 'name:s.128', # name of group - 'comment:s.1024', # internal comment (optional, for admins) - 'priority:i', # priority, used for order in group-list - # (from 0-highest to 99-lowest) - @sharedAttributes, - ], - 'group_client_ref' => [ + 'cols' => [ + 'id:pk', # primary key + 'name:s.128', # name of group + 'priority:i', # priority, used for order in group-list + # (from 0-highest to 99-lowest) + 'comment:s.1024', # internal comment (optional, for admins) + ], + }, + 'group_client_ref' => { # groups referring to their clients - 'group_id:fk', # foreign key - 'client_id:fk', # foreign key - ], - 'group_system_ref' => [ + 'cols' => [ + 'group_id:fk', # foreign key + 'client_id:fk', # foreign key + ], + }, + 'group_system_ref' => { # groups referring to the systems each of their clients should # offer for booting - 'group_id:fk', # foreign key - 'system_id:fk', # foreign key - ], - 'global_info' => [ - # a home for global counters and other info - 'id:s.32', # key - 'value:s.128', # value - ], + 'cols' => [ + 'group_id:fk', # foreign key + 'system_id:fk', # foreign key + ], + }, + 'meta' => { + # information about the database as such + 'cols' => [ + 'schema_version:s.5', # schema-version currently implemented by DB + ], + 'vals' => [ + { + 'schema_version' => $DbSchema->{'version'}, + }, + ], + }, + 'system' => { + # a system describes one bootable instance of an export, it + # represents a selectable line in the PXE boot menu of all the + # clients associated with this system + 'cols' => [ + 'id:pk', # primary key + 'export_id:fk', # foreign key + 'name:s.64', # unique name of system, is automatically + # constructed like this: + # -- + 'label:s.64', # name visible to user (pxe-label) + # if empty, this will be autocreated from + # the name + 'kernel:s.128', # path to kernel file, relative to /boot + 'kernel_params:s.512', # kernel-param string for pxe + 'hidden:b', # hidden systems won't be offered for booting + 'comment:s.1024', # internal comment (optional, for admins) + ], + 'vals' => [ + { # add default system + 'id' => 0, + 'name' => '<<>>', + 'hidden' => 1, + 'comment' => 'internal system that holds default values', + }, + ], + }, + 'system_attr' => { + # attributes of systems + 'cols' => [ + 'id:pk', # primary key + 'system_id:fk', # foreign key to system + 'name:s.128', # attribute name + 'value:s.255', # attribute value + ], + 'vals' => [ + # attributes of default system + { + 'system_id' => 0, + 'name' => 'automnt_dir', + 'value' => '', + }, + { + 'system_id' => 0, + 'name' => 'automnt_src', + 'value' => '', + }, + { + 'system_id' => 0, + 'name' => 'country', + 'value' => "$country", + }, + { + 'system_id' => 0, + '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', + 'value' => 'no', + }, + { + 'system_id' => 0, + '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_nicmods', + 'value' + => 'forcedeth e1000 e100 tg3 via-rhine r8169 pcnet32', + }, + { + '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', + 'value' => 'yes', + }, + { + 'system_id' => 0, + 'name' => 'start_atd', + 'value' => 'no', + }, + { + 'system_id' => 0, + 'name' => 'start_cron', + 'value' => 'no', + }, + { + 'system_id' => 0, + 'name' => 'start_dreshal', + 'value' => 'yes', + }, + { + 'system_id' => 0, + 'name' => 'start_ntp', + 'value' => 'initial', + }, + { + 'system_id' => 0, + 'name' => 'start_nfsv4', + 'value' => 'no', + }, + { + 'system_id' => 0, + 'name' => 'start_printer', + 'value' => 'no', + }, + { + 'system_id' => 0, + 'name' => 'start_samba', + 'value' => 'may', + }, + { + 'system_id' => 0, + 'name' => 'start_snmp', + 'value' => 'no', + }, + { + 'system_id' => 0, + 'name' => 'start_sshd', + 'value' => 'yes', + }, + { + 'system_id' => 0, + 'name' => 'start_syslog', + 'value' => 'yes', + }, + { + 'system_id' => 0, + 'name' => 'start_x', + 'value' => 'yes', + }, + { + 'system_id' => 0, + 'name' => 'start_xdmcp', + 'value' => 'kdm', + }, + { + 'system_id' => 0, + 'name' => 'tex_enable', + 'value' => 'no', + }, + { + 'system_id' => 0, + 'name' => 'timezone', + 'value' => 'Europe/Berlin', + }, + { + 'system_id' => 0, + 'name' => 'tvout', + 'value' => 'no', + }, + { + 'system_id' => 0, + 'name' => 'vmware', + 'value' => 'no', + }, + ], + }, + 'vendor_os' => { + # a vendor-OS describes a folder containing an operating system as + # provided by the vendor (a.k.a. unchanged and thus updatable) + 'cols' => [ + 'id:pk', # primary key + 'name:s.48', # structured name of OS installation + # (e.g. suse-9.3-kde, debian-3.1-ppc, + # suse-10.2-cloned-from-kiwi). + # This is used as the folder name for the + # corresponding stage1, too. + 'comment:s.1024', # internal comment (optional, for admins) + 'clone_source:s.255', # if vendor-OS was cloned, this contains + # the rsync-URI pointing to the original + ], + }, }, }; ################################################################################ ### DB-schema history +### ### This hash contains a description of all the different changes that have ### taken place on the schema. Each version contains a changeset (array) ### with the commands that take the schema from the last version to the ### current. +### ### The following 'cmd'-types are supported: +### ### add-table => creates a new table ### 'table' => contains the name of the new table ### 'cols' => contains a list of column descriptions ### 'vals' => optional, contains list of data hashes to be inserted ### into new table +### ### drop-table => drops an existing table ### 'table => contains the name of the table to be dropped +### ### rename-table => renames a table ### 'old-table' => contains the old name of the table ### 'new-table' => contains the new name of the table +### 'cols' => contains a full list of column descriptions +### ### add-columns => adds columns to a table ### 'table' => the name of the table the columns should be added to ### 'new-cols' => contains a list of new column descriptions ### 'new-default-vals' => optional, a list of data hashes to be used ### as default values for the new columns ### 'cols' => contains a full list of resulting column descriptions +### ### drop-columns => drops columns from a table ### 'table' => the name of the table the columns should be dropped from -### 'col-changes' => a hash with changed column descriptions +### 'drop-cols' => a list of column names to be dropped ### 'cols' => contains a full list of resulting column descriptions +### +### perl-func => a perl function invoked with config-DB object as param +### 'code' => the function (sub) that shall be executed +### ################################################################################ -use POSIX qw(locale_h); -my $lang = setlocale(LC_MESSAGES); -my $country; -if ($lang =~ m[^\w\w_(\w\w)]) { - $country = lc($1); -} else { - $country = 'us'; -} - %DbSchemaHistory = ( '0.01' => [ - # the initial schema version simply adds a couple of tables: + # there's no need to upgrade to the initial schema version, as we + # create the newest schema automatically if none exists yet. + ], + '0.2' => [ + # move attributes into separate tables ... + # + # ... system attributes ... { 'cmd' => 'add-table', - 'table' => 'meta', - 'cols' => $DbSchema->{'tables'}->{'meta'}, - 'vals' => [ - { # add initial meta info - 'schema_version' => $DbSchema->{'version'}, - }, + 'table' => 'system_attr', + 'cols' => [ + 'id:pk', + 'system_id:fk', + 'name:s.128', + 'value:s.255', ], }, { - 'cmd' => 'add-table', - 'table' => 'vendor_os', - 'cols' => $DbSchema->{'tables'}->{'vendor_os'}, - }, - { - 'cmd' => 'add-table', - 'table' => 'export', - 'cols' => $DbSchema->{'tables'}->{'export'}, + 'cmd' => 'perl-func', + 'code' => sub { + my $configDB = shift; + foreach my $system ($configDB->fetchSystemByFilter()) { + foreach my $key (keys %$system) { + next if substr($key, 0, 5) ne 'attr_'; + my $attrValue = $system->{$key} || ''; + next if !length($attrValue); + my $newAttrName = substr($key, 5); + $configDB->setSystemAttr( + $system->{id}, $newAttrName, $attrValue + ); + } + } + 1; + } }, { - 'cmd' => 'add-table', + 'cmd' => 'drop-columns', 'table' => 'system', - 'cols' => $DbSchema->{'tables'}->{'system'}, - 'vals' => [ - { # add default system - 'id' => 0, - 'name' => '<<>>', - 'hidden' => 1, - 'comment' => 'internal system that holds default values', - # system-only attributes: - 'attr_ramfs_nicmods' - => 'forcedeth e1000 e100 tg3 via-rhine r8169 pcnet32', - 'attr_ramfs_fsmods' => '', - # real attributes: - 'attr_automnt_dir' => '', - 'attr_automnt_src' => '', - 'attr_country' => "$country", - 'attr_dm_allow_shutdown' => 'user', - 'attr_hw_graphic' => '', - 'attr_hw_monitor' => '', - 'attr_hw_mouse' => '', - 'attr_late_dm' => 'no', - 'attr_netbios_workgroup' => 'slx-network', - 'attr_nis_domain' => '', - 'attr_nis_servers' => '', - 'attr_sane_scanner' => '', - 'attr_scratch' => '', - 'attr_slxgrp' => '', - 'attr_start_alsasound' => 'yes', - 'attr_start_atd' => 'no', - 'attr_start_cron' => 'no', - 'attr_start_dreshal' => 'yes', - 'attr_start_ntp' => 'initial', - 'attr_start_nfsv4' => 'no', - 'attr_start_printer' => 'no', - 'attr_start_samba' => 'may', - 'attr_start_snmp' => 'no', - 'attr_start_sshd' => 'yes', - 'attr_start_syslog' => 'yes', - 'attr_start_x' => 'yes', - 'attr_start_xdmcp' => 'kdm', - 'attr_tex_enable' => 'no', - 'attr_timezone' => 'Europe/Berlin', - 'attr_tvout' => 'no', - 'attr_vmware' => 'no', - }, + 'drop-cols' => [ + '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', ], - }, - { - 'cmd' => 'add-table', - 'table' => 'client', - 'cols' => $DbSchema->{'tables'}->{'client'}, - 'vals' => [ - { # add default client - 'id' => 0, - 'name' => '<<>>', - 'comment' => 'internal client that holds default values', - }, - ], - }, - { - 'cmd' => 'add-table', - 'table' => 'client_system_ref', - 'cols' => $DbSchema->{'tables'}->{'client_system_ref'}, - }, - { - 'cmd' => 'add-table', - 'table' => 'groups', - 'cols' => $DbSchema->{'tables'}->{'groups'}, - }, - { - 'cmd' => 'add-table', - 'table' => 'group_client_ref', - 'cols' => $DbSchema->{'tables'}->{'group_client_ref'}, - }, - { - 'cmd' => 'add-table', - 'table' => 'group_system_ref', - 'cols' => $DbSchema->{'tables'}->{'group_system_ref'}, - }, - { - 'cmd' => 'add-table', - 'table' => 'global_info', - 'cols' => $DbSchema->{'tables'}->{'global_info'}, - 'vals' => [ - { # add nbd-server-port - 'id' => 'next-nbd-server-port', - 'value' => '5000', - }, + 'cols' => [ + '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 ... + # + # ... group attributes ... ], ); diff --git a/config-db/OpenSLX/MetaDB/Base.pm b/config-db/OpenSLX/MetaDB/Base.pm index 7c4a8f3b..13ebe171 100644 --- a/config-db/OpenSLX/MetaDB/Base.pm +++ b/config-db/OpenSLX/MetaDB/Base.pm @@ -218,11 +218,19 @@ sub schemaFetchDBVersion { } -sub schemaConvertTypeDescrToNative +sub schemaSetDBVersion +{ +} + +sub schemaCreate { } -sub schemaDeclareTable +sub schemaUpgradeToCurrent +{ +} + +sub schemaConvertTypeDescrToNative { } diff --git a/config-db/OpenSLX/MetaDB/DBI.pm b/config-db/OpenSLX/MetaDB/DBI.pm index a1b782c1..dbc1faa8 100644 --- a/config-db/OpenSLX/MetaDB/DBI.pm +++ b/config-db/OpenSLX/MetaDB/DBI.pm @@ -221,6 +221,18 @@ sub fetchSystemByID return $self->_doSelect($sql); } +sub fetchSystemAttrs +{ + my $self = shift; + my $systemID = $self->{dbh}->quote(shift); + + my $sql = <<" End-of-Here"; + SELECT id, name, value FROM system_attr + WHERE system_id = $systemID + End-of-Here + return $self->_doSelect($sql); +} + sub fetchSystemIDsOfExport { my $self = shift; @@ -626,6 +638,36 @@ sub changeSystem return $self->_doUpdate('system', $systemIDs, $valRows); } +sub setSystemAttr +{ + my $self = shift; + my $systemID = shift; + my $attrName = shift; + my $attrValue = shift; + + my $quotedSystemID = $self->{dbh}->quote($systemID); + my $quotedAttrName = $self->{dbh}->quote($attrName); + + my $sql = <<" End-of-Here"; + SELECT id FROM system_attr + WHERE system_id = $quotedSystemID + AND name = $quotedAttrName + End-of-Here + my $id = $self->_doSelect($sql, 'id'); + if ($id) { + return $self->_doUpdate( + 'system_attr', [ $id ], [ { value => $attrValue } ] + ); + } + return $self->_doInsert( + 'system_attr', [ { + system_id => $systemID, + name => $attrName, + value => $attrValue, + } ] + ); +} + sub setClientIDsOfSystem { my $self = shift; @@ -800,7 +842,7 @@ sub schemaFetchDBVersion { my $self = shift; - my $dbh = $self->{'dbh'}; + my $dbh = $self->{dbh}; local $dbh->{RaiseError} = 1; my $row = eval { $dbh->selectrow_hashref('SELECT schema_version FROM meta'); }; @@ -811,6 +853,17 @@ sub schemaFetchDBVersion return $row->{schema_version}; } +sub schemaSetDBVersion +{ + my $self = shift; + my $dbVersion = shift; + + $self->{dbh}->do("UPDATE meta SET schema_version = '$dbVersion'") + or croak _tr('Unable to set DB-schema version to %s!', $dbVersion); + + return 1; +} + sub schemaConvertTypeDescrToNative { # a default implementation, many DBs need to override... my $self = shift; @@ -870,14 +923,14 @@ sub schemaDropTable } sub schemaRenameTable -{ # a rather simple-minded implementation that renames a table in several - # steps: - # - create the new table - # - copy the data over from the old one - # - drop the old table - # This should be overriden for advanced DBs, as these more often than not - # implement the 'ALTER TABLE RENAME TO ' SQL-command (which - # is much more efficient). +{ # a rather simple-minded implementation that renames a table in several + # steps: + # - create the new table + # - copy the data over from the old one + # - drop the old table + # This should be overriden for advanced DBs, as these more often than not + # implement the 'ALTER TABLE RENAME TO ' SQL-command (which + # is much more efficient). my $self = shift; my $oldTable = shift; my $newTable = shift; @@ -902,15 +955,15 @@ sub schemaRenameTable } sub schemaAddColumns -{ # a rather simple-minded implementation that adds columns to a table - # in several steps: - # - create a temp table with the new layout - # - copy the data from the old table into the new one - # - drop the old table - # - rename the temp table to the original name - # This should be overriden for advanced DBs, as these more often than not - # implement the 'ALTER TABLE RENAME TO ' SQL-command (which - # is much more efficient). +{ # a rather simple-minded implementation that adds columns to a table + # in several steps: + # - create a temp table with the new layout + # - copy the data from the old table into the new one + # - drop the old table + # - rename the temp table to the original name + # This should be overriden for advanced DBs, as these more often than not + # implement the 'ALTER TABLE ADD COLUMN ' SQL-command (which + # is much more efficient). my $self = shift; my $table = shift; my $newColDescrs = shift; @@ -944,15 +997,15 @@ sub schemaAddColumns } sub schemaDropColumns -{ # a rather simple-minded implementation that drops columns from a table - # in several steps: - # - create a temp table with the new layout - # - copy the data from the old table into the new one - # - drop the old table - # - rename the temp table to the original name - # This should be overriden for advanced DBs, as these sometimes - # implement the 'ALTER TABLE DROP COLUMN ' SQL-command (which - # is much more efficient). +{ # a rather simple-minded implementation that drops columns from a table + # in several steps: + # - create a temp table with the new layout + # - copy the data from the old table into the new one + # - drop the old table + # - rename the temp table to the original name + # This should be overriden for advanced DBs, as these sometimes + # implement the 'ALTER TABLE
DROP COLUMN ' SQL-command (which + # is much more efficient). my $self = shift; my $table = shift; my $dropColNames = shift; @@ -977,15 +1030,15 @@ sub schemaDropColumns } sub schemaChangeColumns -{ # a rather simple-minded implementation that changes columns - # in several steps: - # - create a temp table with the new layout - # - copy the data from the old table into the new one - # - drop the old table - # - rename the temp table to the original name - # This should be overriden for advanced DBs, as these sometimes - # implement the 'ALTER TABLE CHANGE COLUMN ' SQL-command (which - # is much more efficient). +{ # a rather simple-minded implementation that changes columns + # in several steps: + # - create a temp table with the new layout + # - copy the data from the old table into the new one + # - drop the old table + # - rename the temp table to the original name + # This should be overriden for advanced DBs, as these sometimes + # implement the 'ALTER TABLE
CHANGE COLUMN ' SQL-command (which + # is much more efficient). my $self = shift; my $table = shift; my $colChanges = shift; -- cgit v1.2.3-55-g7522