# 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/
# -----------------------------------------------------------------------------
# DBSchema.pm
# - provides database schema of the OpenSLX config-db.
# -----------------------------------------------------------------------------
package OpenSLX::DBSchema;
use strict;
use warnings;
our (@ISA, @EXPORT, $VERSION);
use Exporter;
$VERSION = 0.2;
@ISA = qw(Exporter);
@EXPORT = qw(
$DbSchema %DbSchemaHistory %AttributeInfo
);
our ($DbSchema, %DbSchemaHistory, %AttributeInfo);
use OpenSLX::Basics;
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 (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:
### b => boolean (providing the values 1 and 0 only)
### i => integer (32-bit, signed)
### s.20 => string, followed by length argument (in this case: 20)
### pk => primary key (integer)
### fk => foreign key (integer)
################################################################################
$DbSchema = {
'version' => $VERSION,
'tables' => {
'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' => '<<<default>>>',
'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.
'cols' => [
'id:pk', # primary key
'name:s.64', # unique name of export, is automatically
# constructed like this:
# <vendor-os-name>-<export-type>
'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 for each incarnation, if that's the
# case you can specify it here
'uri:s.255', # path to export (squashfs or NFS-path), if
# empty it will be auto-generated by
# config-demuxer
],
},
'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.
'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
'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
'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:
# <vendor-os-name>-<export-type>-<kernel>
'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' => '<<<default>>>',
'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_miscmods',
'value' => '',
},
{
'system_id' => 0,
'name' => 'ramfs_nicmods',
'value'
=> 'forcedeth e1000 e100 tg3 via-rhine r8169 pcnet32',
},
{
'system_id' => 0,
'name' => 'ramfs_screen',
'value' => '',
},
{
'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
### '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
###
################################################################################
%DbSchemaHistory = (
'0.01' => [
# 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' => 'system_attr',
'cols' => [
'id:pk',
'system_id:fk',
'name:s.128',
'value:s.255',
],
},
{
'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 $system->{id}>0 && !length($attrValue);
my $newAttrName = substr($key, 5);
$configDB->setSystemAttr(
$system->{id}, $newAttrName, $attrValue
);
}
}
1;
}
},
{
'cmd' => 'drop-columns',
'table' => 'system',
'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',
],
'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 ...
],
);
################################################################################
###
### Load all available AttrInfo modules and build the complete hash containing
### info about all known attributes from that.
###
################################################################################
%AttributeInfo = ();
my $libPath = "$openslxConfig{'base-path'}/lib";
foreach my $module (glob("$libPath/OpenSLX/AttrInfo/*.pm")) {
next if $module !~ m{/([^/]+)\.pm$};
my $class = "OpenSLX::AttrInfo::$1";
vlog(2, "loading attr-info from module '$module'");
my $instance = instantiateClass($class);
my $attrInfo = $instance->AttrInfo();
foreach my $attr (keys %$attrInfo) {
$AttributeInfo{$attr} = $attrInfo->{$attr};
}
}
1;