Skip to content

Commit 3250e5e

Browse files
committed
Implemented: FS#1219 - Add support for incremental updates of the ispconfig database structure
1 parent e4aa207 commit 3250e5e

File tree

6 files changed

+163
-23
lines changed

6 files changed

+163
-23
lines changed

install/lib/install.lib.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,43 @@ function is_installed($appname) {
640640
}
641641
}
642642

643+
/*
644+
* Compare ISPConfig version number.
645+
* return values:
646+
* -1 $current version is newer then $new version (downgrade)
647+
* 0 $current version = $new version
648+
* 1 $current version is older then new version (update)
649+
650+
*/
651+
function compare_ispconfig_version($current,$new) {
652+
if( $current == $new) {
653+
return 0;
654+
}
655+
656+
$p = explode('.',$current);
657+
$tmp = '';
658+
$tmp .= str_pad(intval($p[0]), 3, '0', STR_PAD_LEFT);
659+
$tmp .= (isset($p[1]))?str_pad(intval($p[1]), 3, '0', STR_PAD_LEFT):'000';
660+
$tmp .= (isset($p[2]))?str_pad(intval($p[2]), 3, '0', STR_PAD_LEFT):'000';
661+
$tmp .= (isset($p[3]))?str_pad(intval($p[3]), 3, '0', STR_PAD_LEFT):'000';
662+
$current = $tmp;
663+
664+
$p = explode('.',$new);
665+
$tmp = '';
666+
$tmp .= str_pad(intval($p[0]), 3, '0', STR_PAD_LEFT);
667+
$tmp .= (isset($p[1]))?str_pad(intval($p[1]), 3, '0', STR_PAD_LEFT):'000';
668+
$tmp .= (isset($p[2]))?str_pad(intval($p[2]), 3, '0', STR_PAD_LEFT):'000';
669+
$tmp .= (isset($p[3]))?str_pad(intval($p[3]), 3, '0', STR_PAD_LEFT):'000';
670+
$new = $tmp;
671+
672+
if($new > $current) {
673+
return 1;
674+
} else {
675+
return -1;
676+
}
677+
678+
}
679+
643680

644681

645682
?>

install/lib/installer_base.lib.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ public function add_database_server_record() {
196196

197197
$tpl_ini_array = ini_to_array(rf('tpl/server.ini.master'));
198198

199-
// TODO: Update further distribution specific parameters for server config here
199+
//* Update further distribution specific parameters for server config here
200+
//* HINT: Every line added here has to be added in update.lib.php too!!
200201
$tpl_ini_array['web']['vhost_conf_dir'] = $conf['apache']['vhost_conf_dir'];
201202
$tpl_ini_array['web']['vhost_conf_enabled_dir'] = $conf['apache']['vhost_conf_enabled_dir'];
202203
$tpl_ini_array['jailkit']['jailkit_chroot_app_programs'] = $conf['jailkit']['jailkit_chroot_app_programs'];
@@ -637,8 +638,6 @@ public function configure_pam() {
637638
//* configure pam for SMTP authentication agains the ispconfig database
638639
$configfile = 'pamd_smtp';
639640
if(is_file("$pam/smtp")) copy("$pam/smtp", "$pam/smtp~");
640-
// On some OSes smtp is world readable which allows for reading database information. Removing world readable rights should have no effect.
641-
if(is_file("$pam/smtp")) exec("chmod o= $pam/smtp");
642641
if(is_file("$pam/smtp~")) exec("chmod 400 $pam/smtp~");
643642

644643
$content = rf("tpl/$configfile.master");
@@ -647,6 +646,8 @@ public function configure_pam() {
647646
$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
648647
$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
649648
wf("$pam/smtp", $content);
649+
// On some OSes smtp is world readable which allows for reading database information. Removing world readable rights should have no effect.
650+
if(is_file("$pam/smtp")) exec("chmod o= $pam/smtp");
650651
exec("chmod 660 $pam/smtp");
651652
exec("chown daemon:daemon $pam/smtp");
652653

install/lib/update.lib.php

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ function updateDbAndIni() {
6868
//* Update $conf array with values from the server.ini that shall be preserved
6969
$tmp = $inst->db->queryOneRecord("SELECT * FROM ".$conf["mysql"]["database"].".server WHERE server_id = ".$conf['server_id']);
7070
$ini_array = ini_to_array(stripslashes($tmp['config']));
71+
$current_db_version = (isset($tmp['dbversion']))?intval($tmp['dbversion']):0;
7172

7273
if(count($ini_array) == 0) die('Unable to read server configuration from database.');
7374

@@ -78,31 +79,61 @@ function updateDbAndIni() {
7879
$conf['services']['db'] = ($tmp['db_server'] == 1)?true:false;
7980
$conf['services']['vserver'] = ($tmp['vserver_server'] == 1)?true:false;
8081
$conf['postfix']['vmail_mailbox_base'] = $ini_array['mail']['homedir_path'];
81-
82-
//** Delete the old database
83-
if( !$inst->db->query('DROP DATABASE IF EXISTS '.$conf['mysql']['database']) ) {
84-
82+
83+
//* Do incremental DB updates only on installed ISPConfig versions > 3.0.3
84+
if(compare_ispconfig_version('3.0.3',ISPC_APP_VERSION) >= 0) {
85+
86+
swriteln($inst->lng('Starting incremental database update.'));
87+
88+
//* get the version of the db schema from the server table
89+
$found = true;
90+
while($found == true) {
91+
$next_db_version = intval($current_db_version + 1);
92+
$patch_filename = realpath(dirname(__FILE__).'/../').'/sql/incremental/upd_'.str_pad($next_db_version, 4, '0', STR_PAD_LEFT).'.sql';
93+
if(is_file($patch_filename)) {
94+
//* Load patch file into database
95+
if( !empty($conf["mysql"]["admin_password"]) ) {
96+
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);
97+
} else {
98+
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' ".$conf['mysql']['database']." < ".$patch_filename);
99+
}
100+
swriteln($inst->lng('Loading SQL patch file').': '.$patch_filename);
101+
$current_db_version = $next_db_version;
102+
} else {
103+
$found = false;
104+
}
105+
}
106+
107+
//* update the database version in server table
108+
$inst->db->query("UPDATE ".$conf["mysql"]["database"].".server SET dbversion = '".$current_db_version."' WHERE server_id = ".$conf['server_id']);
109+
110+
111+
//* If ISPConfig Version < 3.0.3, we will do a full db update
112+
} else {
113+
114+
swriteln($inst->lng('Starting full database update.'));
115+
116+
//** Delete the old database
117+
if( !$inst->db->query('DROP DATABASE IF EXISTS '.$conf['mysql']['database']) ) {
85118
$inst->error('Unable to drop MySQL database: '.$conf['mysql']['database'].'.');
86-
}
87-
88-
//** Create the mysql database
89-
$inst->configure_database();
90-
91-
//** empty all databases
92-
$db_tables = $inst->db->getTables();
93-
94-
foreach($db_tables as $table) {
119+
}
95120

96-
$inst->db->query("TRUNCATE $table");
97-
}
121+
//** Create the mysql database
122+
$inst->configure_database();
98123

99-
//** load old data back into database
100-
if( !empty($conf["mysql"]["admin_password"]) ) {
124+
//** empty all databases
125+
$db_tables = $inst->db->getTables();
101126

102-
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");
103-
} else {
127+
foreach($db_tables as $table) {
128+
$inst->db->query("TRUNCATE $table");
129+
}
104130

105-
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' ".$conf['mysql']['database']." < existing_db.sql");
131+
//** load old data back into database
132+
if( !empty($conf["mysql"]["admin_password"]) ) {
133+
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");
134+
} else {
135+
system("mysql --default-character-set=".$conf['mysql']['charset']." --force -h '".$conf['mysql']['host']."' -u '".$conf['mysql']['admin_user']."' ".$conf['mysql']['database']." < existing_db.sql");
136+
}
106137
}
107138

108139

@@ -111,6 +142,32 @@ function updateDbAndIni() {
111142
$old_ini_array = ini_to_array(stripslashes($tmp_server_rec['config']));
112143
unset($tmp_server_rec);
113144
$tpl_ini_array = ini_to_array(rf('tpl/server.ini.master'));
145+
146+
//* Update further distribution specific parameters for server config here
147+
//* HINT: Every line added here has to be added in installer_base.lib.php too!!
148+
$tpl_ini_array['web']['vhost_conf_dir'] = $conf['apache']['vhost_conf_dir'];
149+
$tpl_ini_array['web']['vhost_conf_enabled_dir'] = $conf['apache']['vhost_conf_enabled_dir'];
150+
$tpl_ini_array['jailkit']['jailkit_chroot_app_programs'] = $conf['jailkit']['jailkit_chroot_app_programs'];
151+
$tpl_ini_array['fastcgi']['fastcgi_phpini_path'] = $conf['fastcgi']['fastcgi_phpini_path'];
152+
$tpl_ini_array['fastcgi']['fastcgi_starter_path'] = $conf['fastcgi']['fastcgi_starter_path'];
153+
$tpl_ini_array['server']['hostname'] = $conf['hostname'];
154+
$tpl_ini_array['server']['ip_address'] = @gethostbyname($conf['hostname']);
155+
$tpl_ini_array['web']['website_basedir'] = $conf['web']['website_basedir'];
156+
$tpl_ini_array['web']['website_path'] = $conf['web']['website_path'];
157+
$tpl_ini_array['web']['website_symlinks'] = $conf['web']['website_symlinks'];
158+
$tpl_ini_array['cron']['crontab_dir'] = $conf['cron']['crontab_dir'];
159+
$tpl_ini_array['web']['security_level'] = 20;
160+
$tpl_ini_array['web']['user'] = $conf['apache']['user'];
161+
$tpl_ini_array['web']['group'] = $conf['apache']['group'];
162+
$tpl_ini_array['web']['php_ini_path_apache'] = $conf['apache']['php_ini_path_apache'];
163+
$tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi'];
164+
$tpl_ini_array['mail']['pop3_imap_daemon'] = ($conf['dovecot']['installed'] == true)?'dovecot':'courier';
165+
$tpl_ini_array['mail']['mail_filter_syntax'] = ($conf['dovecot']['installed'] == true)?'sieve':'maildrop';
166+
$tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user'];
167+
$tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group'];
168+
$tpl_ini_array['dns']['bind_zonefiles_dir'] = $conf['bind']['bind_zonefiles_dir'];
169+
$tpl_ini_array['dns']['named_conf_path'] = $conf['bind']['named_conf_path'];
170+
$tpl_ini_array['dns']['named_conf_local_path'] = $conf['bind']['named_conf_local_path'];
114171

115172
// update the new template with the old values
116173
if(is_array($old_ini_array)) {

install/sql/README.txt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
---------------------------------------------------------------------------------
3+
- Developer README
4+
---------------------------------------------------------------------------------
5+
6+
When you add or modify a database field or table in the ISPConfig database,
7+
then follow these steps:
8+
9+
1) Add the field or table in the ispconfig3.sql file. This file contains the
10+
complete database dump which is used when ISPConfig gets installed.
11+
12+
2) Create a new file in the "incremental" subfolder wich contains the alter
13+
table, or if it is a complete new table then the add table, statement(s) in
14+
MySQL syntax which is/are required to modify the current ispconfig database
15+
during update. The naming scheme of the sql patch update files is
16+
upd_0001.sql, upd_0002.sql, upd_0003.sql etc. Ensure that the number that
17+
you choose for the new file is a +1 increment of the number of the last
18+
existing file and that the number is formatted with 4 digits.
19+
20+
A patch file may contain one or more alter table statements. Every patch file
21+
gets executed once in the database, so do not modify older (already released)
22+
patch files, they will not get executed again if the update was already run
23+
once on a system.
24+
25+
After a patch has been executed, the dbversion field in the server table gets
26+
increeased to the version number of the last installed patch.
27+
28+
If you like to run a patch file again for testing purposes on your dev machine,
29+
then set the number in "dbversion" field of the server table to be lower then
30+
the number of your patch.
31+
32+
Note: Incremental patches are supported for installed ISPConfig versions > 3.0.3.
33+
If the installed version is < 3.0.3, then the full update method is used.
34+
In other words, ISPConfig 3.0.3 is the patch release (dbversion) 0 as the
35+
incremental update feature has been introduced in 3.0.3.
36+
37+
38+
39+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- -----------------------------------------------------------
2+
-- Dummy patch file
3+
-- Do not edit this file
4+
-- See README.txt in sql folder for detailed instructions
5+
-- -----------------------------------------------------------

install/sql/ispconfig3.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ CREATE TABLE `server` (
659659
`config` text NOT NULL,
660660
`updated` bigint(20) unsigned NOT NULL default '0',
661661
`mirror_server_id` int(11) unsigned NOT NULL default '0',
662+
`dbversion` int(11) unsigned NOT NULL default '0',
662663
`active` tinyint(1) NOT NULL default '1',
663664
PRIMARY KEY (`server_id`)
664665
) ENGINE=MyISAM AUTO_INCREMENT=1;

0 commit comments

Comments
 (0)