Commit 3250e5e3 authored by tbrehm's avatar tbrehm
Browse files

Implemented: FS#1219 - Add support for incremental updates of the ispconfig database structure

parent e4aa2075
......@@ -640,6 +640,43 @@ function is_installed($appname) {
}
}
/*
* Compare ISPConfig version number.
* return values:
* -1 $current version is newer then $new version (downgrade)
* 0 $current version = $new version
* 1 $current version is older then new version (update)
*/
function compare_ispconfig_version($current,$new) {
if( $current == $new) {
return 0;
}
$p = explode('.',$current);
$tmp = '';
$tmp .= str_pad(intval($p[0]), 3, '0', STR_PAD_LEFT);
$tmp .= (isset($p[1]))?str_pad(intval($p[1]), 3, '0', STR_PAD_LEFT):'000';
$tmp .= (isset($p[2]))?str_pad(intval($p[2]), 3, '0', STR_PAD_LEFT):'000';
$tmp .= (isset($p[3]))?str_pad(intval($p[3]), 3, '0', STR_PAD_LEFT):'000';
$current = $tmp;
$p = explode('.',$new);
$tmp = '';
$tmp .= str_pad(intval($p[0]), 3, '0', STR_PAD_LEFT);
$tmp .= (isset($p[1]))?str_pad(intval($p[1]), 3, '0', STR_PAD_LEFT):'000';
$tmp .= (isset($p[2]))?str_pad(intval($p[2]), 3, '0', STR_PAD_LEFT):'000';
$tmp .= (isset($p[3]))?str_pad(intval($p[3]), 3, '0', STR_PAD_LEFT):'000';
$new = $tmp;
if($new > $current) {
return 1;
} else {
return -1;
}
}
?>
......@@ -196,7 +196,8 @@ class installer_base {
$tpl_ini_array = ini_to_array(rf('tpl/server.ini.master'));
// TODO: Update further distribution specific parameters for server config here
//* Update further distribution specific parameters for server config here
//* HINT: Every line added here has to be added in update.lib.php too!!
$tpl_ini_array['web']['vhost_conf_dir'] = $conf['apache']['vhost_conf_dir'];
$tpl_ini_array['web']['vhost_conf_enabled_dir'] = $conf['apache']['vhost_conf_enabled_dir'];
$tpl_ini_array['jailkit']['jailkit_chroot_app_programs'] = $conf['jailkit']['jailkit_chroot_app_programs'];
......@@ -637,8 +638,6 @@ class installer_base {
//* configure pam for SMTP authentication agains the ispconfig database
$configfile = 'pamd_smtp';
if(is_file("$pam/smtp")) copy("$pam/smtp", "$pam/smtp~");
// On some OSes smtp is world readable which allows for reading database information. Removing world readable rights should have no effect.
if(is_file("$pam/smtp")) exec("chmod o= $pam/smtp");
if(is_file("$pam/smtp~")) exec("chmod 400 $pam/smtp~");
$content = rf("tpl/$configfile.master");
......@@ -647,6 +646,8 @@ class installer_base {
$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
wf("$pam/smtp", $content);
// On some OSes smtp is world readable which allows for reading database information. Removing world readable rights should have no effect.
if(is_file("$pam/smtp")) exec("chmod o= $pam/smtp");
exec("chmod 660 $pam/smtp");
exec("chown daemon:daemon $pam/smtp");
......
......@@ -68,6 +68,7 @@ function updateDbAndIni() {
//* Update $conf array with values from the server.ini that shall be preserved
$tmp = $inst->db->queryOneRecord("SELECT * FROM ".$conf["mysql"]["database"].".server WHERE server_id = ".$conf['server_id']);
$ini_array = ini_to_array(stripslashes($tmp['config']));
$current_db_version = (isset($tmp['dbversion']))?intval($tmp['dbversion']):0;
if(count($ini_array) == 0) die('Unable to read server configuration from database.');
......@@ -78,31 +79,61 @@ function updateDbAndIni() {
$conf['services']['db'] = ($tmp['db_server'] == 1)?true:false;
$conf['services']['vserver'] = ($tmp['vserver_server'] == 1)?true:false;
$conf['postfix']['vmail_mailbox_base'] = $ini_array['mail']['homedir_path'];
//** Delete the old database
if( !$inst->db->query('DROP DATABASE IF EXISTS '.$conf['mysql']['database']) ) {
//* Do incremental DB updates only on installed ISPConfig versions > 3.0.3
if(compare_ispconfig_version('3.0.3',ISPC_APP_VERSION) >= 0) {
swriteln($inst->lng('Starting incremental database update.'));
//* get the version of the db schema from the server table
$found = true;
while($found == true) {
$next_db_version = intval($current_db_version + 1);
$patch_filename = realpath(dirname(__FILE__).'/../').'/sql/incremental/upd_'.str_pad($next_db_version, 4, '0', STR_PAD_LEFT).'.sql';
if(is_file($patch_filename)) {
//* Load patch file into database
if( !empty($conf["mysql"]["admin_password"]) ) {
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' ".$conf['mysql']['database']." < ".$patch_filename);
} else {
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' ".$conf['mysql']['database']." < ".$patch_filename);
}
swriteln($inst->lng('Loading SQL patch file').': '.$patch_filename);
$current_db_version = $next_db_version;
} else {
$found = false;
}
}
//* update the database version in server table
$inst->db->query("UPDATE ".$conf["mysql"]["database"].".server SET dbversion = '".$current_db_version."' WHERE server_id = ".$conf['server_id']);
//* If ISPConfig Version < 3.0.3, we will do a full db update
} else {
swriteln($inst->lng('Starting full database update.'));
//** Delete the old database
if( !$inst->db->query('DROP DATABASE IF EXISTS '.$conf['mysql']['database']) ) {
$inst->error('Unable to drop MySQL database: '.$conf['mysql']['database'].'.');
}
//** Create the mysql database
$inst->configure_database();
//** empty all databases
$db_tables = $inst->db->getTables();
foreach($db_tables as $table) {
}
$inst->db->query("TRUNCATE $table");
}
//** Create the mysql database
$inst->configure_database();
//** load old data back into database
if( !empty($conf["mysql"]["admin_password"]) ) {
//** empty all databases
$db_tables = $inst->db->getTables();
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' ".$conf['mysql']['database']." < existing_db.sql");
} else {
foreach($db_tables as $table) {
$inst->db->query("TRUNCATE $table");
}
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' ".$conf['mysql']['database']." < existing_db.sql");
//** load old data back into database
if( !empty($conf["mysql"]["admin_password"]) ) {
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' -p'".$conf['mysql']['admin_password']."' ".$conf['mysql']['database']." < existing_db.sql");
} else {
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' ".$conf['mysql']['database']." < existing_db.sql");
}
}
......@@ -111,6 +142,32 @@ function updateDbAndIni() {
$old_ini_array = ini_to_array(stripslashes($tmp_server_rec['config']));
unset($tmp_server_rec);
$tpl_ini_array = ini_to_array(rf('tpl/server.ini.master'));
//* Update further distribution specific parameters for server config here
//* HINT: Every line added here has to be added in installer_base.lib.php too!!
$tpl_ini_array['web']['vhost_conf_dir'] = $conf['apache']['vhost_conf_dir'];
$tpl_ini_array['web']['vhost_conf_enabled_dir'] = $conf['apache']['vhost_conf_enabled_dir'];
$tpl_ini_array['jailkit']['jailkit_chroot_app_programs'] = $conf['jailkit']['jailkit_chroot_app_programs'];
$tpl_ini_array['fastcgi']['fastcgi_phpini_path'] = $conf['fastcgi']['fastcgi_phpini_path'];
$tpl_ini_array['fastcgi']['fastcgi_starter_path'] = $conf['fastcgi']['fastcgi_starter_path'];
$tpl_ini_array['server']['hostname'] = $conf['hostname'];
$tpl_ini_array['server']['ip_address'] = @gethostbyname($conf['hostname']);
$tpl_ini_array['web']['website_basedir'] = $conf['web']['website_basedir'];
$tpl_ini_array['web']['website_path'] = $conf['web']['website_path'];
$tpl_ini_array['web']['website_symlinks'] = $conf['web']['website_symlinks'];
$tpl_ini_array['cron']['crontab_dir'] = $conf['cron']['crontab_dir'];
$tpl_ini_array['web']['security_level'] = 20;
$tpl_ini_array['web']['user'] = $conf['apache']['user'];
$tpl_ini_array['web']['group'] = $conf['apache']['group'];
$tpl_ini_array['web']['php_ini_path_apache'] = $conf['apache']['php_ini_path_apache'];
$tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi'];
$tpl_ini_array['mail']['pop3_imap_daemon'] = ($conf['dovecot']['installed'] == true)?'dovecot':'courier';
$tpl_ini_array['mail']['mail_filter_syntax'] = ($conf['dovecot']['installed'] == true)?'sieve':'maildrop';
$tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user'];
$tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group'];
$tpl_ini_array['dns']['bind_zonefiles_dir'] = $conf['bind']['bind_zonefiles_dir'];
$tpl_ini_array['dns']['named_conf_path'] = $conf['bind']['named_conf_path'];
$tpl_ini_array['dns']['named_conf_local_path'] = $conf['bind']['named_conf_local_path'];
// update the new template with the old values
if(is_array($old_ini_array)) {
......
---------------------------------------------------------------------------------
- Developer README
---------------------------------------------------------------------------------
When you add or modify a database field or table in the ISPConfig database,
then follow these steps:
1) Add the field or table in the ispconfig3.sql file. This file contains the
complete database dump which is used when ISPConfig gets installed.
2) Create a new file in the "incremental" subfolder wich contains the alter
table, or if it is a complete new table then the add table, statement(s) in
MySQL syntax which is/are required to modify the current ispconfig database
during update. The naming scheme of the sql patch update files is
upd_0001.sql, upd_0002.sql, upd_0003.sql etc. Ensure that the number that
you choose for the new file is a +1 increment of the number of the last
existing file and that the number is formatted with 4 digits.
A patch file may contain one or more alter table statements. Every patch file
gets executed once in the database, so do not modify older (already released)
patch files, they will not get executed again if the update was already run
once on a system.
After a patch has been executed, the dbversion field in the server table gets
increeased to the version number of the last installed patch.
If you like to run a patch file again for testing purposes on your dev machine,
then set the number in "dbversion" field of the server table to be lower then
the number of your patch.
Note: Incremental patches are supported for installed ISPConfig versions > 3.0.3.
If the installed version is < 3.0.3, then the full update method is used.
In other words, ISPConfig 3.0.3 is the patch release (dbversion) 0 as the
incremental update feature has been introduced in 3.0.3.
-- -----------------------------------------------------------
-- Dummy patch file
-- Do not edit this file
-- See README.txt in sql folder for detailed instructions
-- -----------------------------------------------------------
\ No newline at end of file
......@@ -659,6 +659,7 @@ CREATE TABLE `server` (
`config` text NOT NULL,
`updated` bigint(20) unsigned NOT NULL default '0',
`mirror_server_id` int(11) unsigned NOT NULL default '0',
`dbversion` int(11) unsigned NOT NULL default '0',
`active` tinyint(1) NOT NULL default '1',
PRIMARY KEY (`server_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment