From 5a43e7a2ea0cf7af35c100cb67e4a53566cbc496 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Fri, 03 Feb 2012 05:58:01 -0500
Subject: [PATCH] - Implemented new backup and restore functions for websites and databases (see also FS#1389) - Added "actions" framework in server to replace the functions provided by the core modules - Moved system update function from remoteactins core module to software update plugin.
---
interface/web/sites/templates/database_edit.htm | 18
server/plugins-available/openvz_plugin.inc.php | 54 +++
interface/web/mail/mail_user_edit.php | 8
interface/web/sites/database_edit.php | 93 +---
install/tpl/server.ini.master | 2
server/plugins-available/software_update_plugin.inc.php | 34 +
interface/web/admin/form/server_config.tform.php | 10
interface/web/admin/templates/server_config_server_edit.htm | 10
interface/web/sites/lib/lang/en_web_backup_list.lng | 16
server/plugins-available/mysql_clientdb_plugin.inc.php | 12
install/sql/ispconfig3.sql | 20 +
server/lib/classes/modules.inc.php | 38 ++
server/mods-available/remoteaction_core_module.inc.php | 7
interface/lib/classes/plugin_backuplist.inc.php | 138 ++++++++
interface/web/sites/templates/web_domain_backup.htm | 2
interface/web/sites/form/database.tform.php | 11
interface/web/themes/default/css/screen/content_ispc.css | 2
interface/web/sites/form/web_domain.tform.php | 11
server/cron_daily.php | 162 +++++++-
interface/web/js/scrigo.js.php | 6
server/plugins-available/backup_plugin.inc.php | 134 +++++++
interface/web/sites/templates/web_backup_list.htm | 40 ++
interface/web/sites/lib/lang/en_database.lng | 5
server/lib/classes/db_mysql.inc.php | 7
server/lib/classes/plugins.inc.php | 42 ++
interface/web/admin/lib/lang/en_server_config.lng | 5
interface/web/sites/web_domain_edit.php | 23 +
interface/web/sites/tools.inc.php | 2
server/server.php | 33 -
server/mods-available/web_module.inc.php | 11
install/sql/incremental/upd_0028.sql | 12
interface/web/sites/web_domain_del.php | 6
32 files changed, 806 insertions(+), 168 deletions(-)
diff --git a/install/sql/incremental/upd_0028.sql b/install/sql/incremental/upd_0028.sql
new file mode 100644
index 0000000..0020cdd
--- /dev/null
+++ b/install/sql/incremental/upd_0028.sql
@@ -0,0 +1,12 @@
+ALTER TABLE `web_database` ADD `parent_domain_id` int(11) unsigned NOT NULL DEFAULT '0' AFTER `server_id`;
+ALTER TABLE `web_database` ADD `backup_interval` VARCHAR( 255 ) NOT NULL DEFAULT 'none', ADD `backup_copies` INT NOT NULL DEFAULT '1' AFTER `remote_ips`;
+CREATE TABLE `web_backup` (
+ `backup_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `server_id` int(10) unsigned NOT NULL,
+ `parent_domain_id` int(10) unsigned NOT NULL,
+ `backup_type` enum('web','mysql') NOT NULL DEFAULT 'web',
+ `backup_mode` varchar(64) NOT NULL DEFAULT '',
+ `tstamp` int(10) unsigned NOT NULL,
+ `filename` varchar(255) NOT NULL,
+ PRIMARY KEY (`backup_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 9c2d5cf..fdd31a8 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -1438,6 +1438,23 @@
-- --------------------------------------------------------
--
+-- Table structure for table `web_backup`
+--
+
+CREATE TABLE `web_backup` (
+ `backup_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `server_id` int(10) unsigned NOT NULL,
+ `parent_domain_id` int(10) unsigned NOT NULL,
+ `backup_type` enum('web','mysql') NOT NULL DEFAULT 'web',
+ `backup_mode` varchar(64) NOT NULL DEFAULT '',
+ `tstamp` int(10) unsigned NOT NULL,
+ `filename` varchar(255) NOT NULL,
+ PRIMARY KEY (`backup_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+
+-- --------------------------------------------------------
+
+--
-- Table structure for table `web_database`
--
@@ -1449,6 +1466,7 @@
`sys_perm_group` varchar(5) DEFAULT NULL,
`sys_perm_other` varchar(5) DEFAULT NULL,
`server_id` int(11) unsigned NOT NULL DEFAULT '0',
+ `parent_domain_id` int(11) unsigned NOT NULL DEFAULT '0',
`type` varchar(16) NOT NULL DEFAULT 'y',
`database_name` varchar(64) DEFAULT NULL,
`database_user` varchar(64) DEFAULT NULL,
@@ -1456,6 +1474,8 @@
`database_charset` varchar(64) DEFAULT NULL,
`remote_access` enum('n','y') NOT NULL DEFAULT 'y',
`remote_ips` text NOT NULL,
+ `backup_interval` VARCHAR( 255 ) NOT NULL DEFAULT 'none',
+ `backup_copies` INT NOT NULL DEFAULT '1',
`active` enum('n','y') NOT NULL DEFAULT 'y',
PRIMARY KEY (`database_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master
index 71e61e6..275fa7a 100644
--- a/install/tpl/server.ini.master
+++ b/install/tpl/server.ini.master
@@ -13,7 +13,7 @@
nameservers=192.168.0.1,192.168.0.2
loglevel=2
backup_dir=/var/backup
-backup_dir_ftpread=n
+backup_mode=rootgz
[mail]
module=postfix_mysql
diff --git a/interface/lib/classes/plugin_backuplist.inc.php b/interface/lib/classes/plugin_backuplist.inc.php
new file mode 100644
index 0000000..ac0396b
--- /dev/null
+++ b/interface/lib/classes/plugin_backuplist.inc.php
@@ -0,0 +1,138 @@
+<?php
+
+/*
+Copyright (c) 2012, Till Brehm, ISPConfig UG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class plugin_backuplist extends plugin_base {
+
+ var $module;
+ var $form;
+ var $tab;
+ var $record_id;
+ var $formdef;
+ var $options;
+
+ function onShow() {
+
+ global $app;
+
+ $listTpl = new tpl;
+ $listTpl->newTemplate('templates/web_backup_list.htm');
+
+ //* Loading language file
+ $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_web_backup_list.lng";
+ include($lng_file);
+ $listTpl->setVar($wb);
+
+ $message = '';
+ $error = '';
+
+ if(isset($_GET['backup_action'])) {
+ $backup_id = intval($_GET['backup_id']);
+
+ if($_GET['backup_action'] == 'download' && $backup_id > 0) {
+ $sql = "SELECT count(action_id) as number FROM sys_remoteaction WHERE action_state = 'pending' AND action_type = 'backup_download' AND action_param = '$backup_id'";
+ $tmp = $app->db->queryOneRecord($sql);
+ if($tmp['number'] == 0) {
+ $message .= $wb['download_info_txt'];
+ $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " .
+ "VALUES (".
+ (int)$this->form->dataRecord['server_id'] . ", " .
+ time() . ", " .
+ "'backup_download', " .
+ "'".$backup_id."', " .
+ "'pending', " .
+ "''" .
+ ")";
+ $app->db->query($sql);
+ } else {
+ $error .= $wb['download_pending_txt'];
+ }
+ }
+ if($_GET['backup_action'] == 'restore' && $backup_id > 0) {
+ $sql = "SELECT count(action_id) as number FROM sys_remoteaction WHERE action_state = 'pending' AND action_type = 'backup_restore' AND action_param = '$backup_id'";
+ $tmp = $app->db->queryOneRecord($sql);
+ if($tmp['number'] == 0) {
+ $message .= $wb['restore_info_txt'];
+ $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " .
+ "VALUES (".
+ (int)$this->form->dataRecord['server_id'] . ", " .
+ time() . ", " .
+ "'backup_restore', " .
+ "'".$backup_id."', " .
+ "'pending', " .
+ "''" .
+ ")";
+ $app->db->query($sql);
+ } else {
+ $error .= $wb['restore_pending_txt'];
+ }
+ }
+
+ }
+
+ //* Get the data
+ $sql = "SELECT * FROM web_backup WHERE parent_domain_id = ".$this->form->id." ORDER BY tstamp DESC, backup_type ASC";
+ $records = $app->db->queryAllRecords($sql);
+
+ $bgcolor = "#FFFFFF";
+ if(is_array($records)) {
+ foreach($records as $rec) {
+
+ // Change of color
+ $bgcolor = ($bgcolor == "#FFFFFF")?"#EEEEEE":"#FFFFFF";
+ $rec["bgcolor"] = $bgcolor;
+
+ $rec['date'] = date($app->lng('conf_format_datetime'),$rec['tstamp']);
+ $rec['backup_type'] = $wb[('backup_type_'.$rec['backup_type'])];
+
+ $records_new[] = $rec;
+ }
+ }
+
+ $listTpl->setLoop('records',@$records_new);
+
+ $listTpl->setVar('parent_id',$this->form->id);
+ $listTpl->setVar('msg',$message);
+ $listTpl->setVar('error',$error);
+
+ // Setting Returnto information in the session
+ $list_name = 'backup_list';
+ // $_SESSION["s"]["list"][$list_name]["parent_id"] = $app->tform_actions->id;
+ $_SESSION["s"]["list"][$list_name]["parent_id"] = $this->form->id;
+ $_SESSION["s"]["list"][$list_name]["parent_name"] = $app->tform->formDef["name"];
+ $_SESSION["s"]["list"][$list_name]["parent_tab"] = $_SESSION["s"]["form"]["tab"];
+ $_SESSION["s"]["list"][$list_name]["parent_script"] = $app->tform->formDef["action"];
+ $_SESSION["s"]["form"]["return_to"] = $list_name;
+
+ return $listTpl->grab();
+ }
+
+}
+
+?>
\ No newline at end of file
diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php
index 027328d..24f3f18 100644
--- a/interface/web/admin/form/server_config.tform.php
+++ b/interface/web/admin/form/server_config.tform.php
@@ -138,11 +138,13 @@
'width' => '40',
'maxlength' => '255'
),
- 'backup_dir_ftpread' => array(
+ 'backup_mode' => array(
'datatype' => 'VARCHAR',
- 'formtype' => 'CHECKBOX',
- 'default' => 'y',
- 'value' => array(0 => 'n', 1 => 'y')
+ 'formtype' => 'SELECT',
+ 'default' => 'userzip',
+ 'value' => array('userzip' => 'backup_mode_userzip', 'rootgz' => 'backup_mode_rootgz'),
+ 'width' => '40',
+ 'maxlength' => '255'
),
##################################
# ENDE Datatable fields
diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng
index ec2e053..4cce275 100644
--- a/interface/web/admin/lib/lang/en_server_config.lng
+++ b/interface/web/admin/lib/lang/en_server_config.lng
@@ -87,7 +87,9 @@
$wb["CA_path_txt"] = 'CA Path';
$wb["CA_pass_txt"] = 'CA passphrase';
$wb["fastcgi_config_syntax_txt"] = 'FastCGI config syntax';
-$wb["backup_dir_ftpread_txt"] = 'Backup dir. readable for website FTP users.';
+$wb["backup_mode_txt"] = 'Backup mode';
+$wb["backup_mode_userzip"] = 'Backup web files owned by web user as zip';
+$wb["backup_mode_rootgz"] = 'Backup all files in web directory as root user';
$wb["server_type_txt"] = 'Server Type';
$wb["nginx_vhost_conf_dir_txt"] = 'Nginx Vhost config dir';
$wb["nginx_vhost_conf_enabled_dir_txt"] = 'Nginx Vhost config enabled dir';
@@ -153,7 +155,6 @@
$wb["add_web_users_to_sshusers_group_txt"] = 'Add web users to -sshusers- group';
$wb["connect_userid_to_webid_txt"] = 'Connect Linux userid to webid';
$wb["connect_userid_to_webid_start_txt"] = 'Start ID for userid/webid connect';
-
$wb["realtime_blackhole_list_txt"] = 'Real-time Blackhole List';
$wb["realtime_blackhole_list_note_txt"] = '(Separate RBL\'s with commas)';
?>
\ No newline at end of file
diff --git a/interface/web/admin/templates/server_config_server_edit.htm b/interface/web/admin/templates/server_config_server_edit.htm
index 8f42d8c..7b777bf 100644
--- a/interface/web/admin/templates/server_config_server_edit.htm
+++ b/interface/web/admin/templates/server_config_server_edit.htm
@@ -43,11 +43,11 @@
<input name="backup_dir" id="backup_dir" value="{tmpl_var name='backup_dir'}" size="40" maxlength="255" type="text" class="textInput" />
</div>
<div class="ctrlHolder">
- <p class="label">{tmpl_var name='backup_dir_ftpread_txt'}</p>
- <div class="multiField">
- {tmpl_var name='backup_dir_ftpread'}
- </div>
- </div>
+ <label for="backup_mode">{tmpl_var name='backup_mode_txt'}</label>
+ <select name="backup_mode" id="backup_mode" class="selectInput">
+ {tmpl_var name='backup_mode'}
+ </select>
+ </div>
</fieldset>
<input type="hidden" name="id" value="{tmpl_var name='id'}">
diff --git a/interface/web/js/scrigo.js.php b/interface/web/js/scrigo.js.php
index 94b7075..f8da538 100644
--- a/interface/web/js/scrigo.js.php
+++ b/interface/web/js/scrigo.js.php
@@ -269,6 +269,12 @@
}
}
+function confirm_action(link,confirmation) {
+ if(window.confirm(confirmation)) {
+ loadContent(link);
+ }
+}
+
function loadContentInto(elementid,pagename) {
var pageContentObject2 = jQuery.ajax({ type: "GET",
url: pagename,
diff --git a/interface/web/mail/mail_user_edit.php b/interface/web/mail/mail_user_edit.php
index f57a4e8..398bf12 100644
--- a/interface/web/mail/mail_user_edit.php
+++ b/interface/web/mail/mail_user_edit.php
@@ -231,14 +231,14 @@
// Spamfilter policy
$policy_id = intval($this->dataRecord["policy"]);
if($policy_id > 0) {
- $tmp_user = $app->db->queryOneRecord("SELECT id FROM spamfilter_users WHERE email = '".mysql_real_escape_string($this->dataRecord["email"])."'");
+ $tmp_user = $app->db->queryOneRecord("SELECT id FROM spamfilter_users WHERE email = '".$app->db->quote($this->dataRecord["email"])."'");
if($tmp_user["id"] > 0) {
// There is already a record that we will update
$app->db->datalogUpdate('spamfilter_users', "policy_id = $policy_id", 'id', $tmp_user["id"]);
} else {
// We create a new record
$insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `priority`, `policy_id`, `email`, `fullname`, `local`)
- VALUES (".$_SESSION["s"]["user"]["userid"].", ".$domain["sys_groupid"].", 'riud', 'riud', '', ".$domain["server_id"].", 10, ".$policy_id.", '".mysql_real_escape_string($this->dataRecord["email"])."', '".mysql_real_escape_string($this->dataRecord["email"])."', 'Y')";
+ VALUES (".$_SESSION["s"]["user"]["userid"].", ".$domain["sys_groupid"].", 'riud', 'riud', '', ".$domain["server_id"].", 10, ".$policy_id.", '".$app->db->quote($this->dataRecord["email"])."', '".$app->db->quote($this->dataRecord["email"])."', 'Y')";
$app->db->datalogInsert('spamfilter_users', $insert_data, 'id');
}
} // endif spamfilter policy
@@ -266,7 +266,7 @@
// Spamfilter policy
$policy_id = intval($this->dataRecord["policy"]);
- $tmp_user = $app->db->queryOneRecord("SELECT id FROM spamfilter_users WHERE email = '".mysql_real_escape_string($this->dataRecord["email"])."'");
+ $tmp_user = $app->db->queryOneRecord("SELECT id FROM spamfilter_users WHERE email = '".$app->db->quote($this->dataRecord["email"])."'");
if($policy_id > 0) {
if($tmp_user["id"] > 0) {
// There is already a record that we will update
@@ -274,7 +274,7 @@
} else {
// We create a new record
$insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `priority`, `policy_id`, `email`, `fullname`, `local`)
- VALUES (".$_SESSION["s"]["user"]["userid"].", ".$domain["sys_groupid"].", 'riud', 'riud', '', ".$domain["server_id"].", 10, ".$policy_id.", '".mysql_real_escape_string($this->dataRecord["email"])."', '".mysql_real_escape_string($this->dataRecord["email"])."', 'Y')";
+ VALUES (".$_SESSION["s"]["user"]["userid"].", ".$domain["sys_groupid"].", 'riud', 'riud', '', ".$domain["server_id"].", 10, ".$policy_id.", '".$app->db->quote($this->dataRecord["email"])."', '".$app->db->quote($this->dataRecord["email"])."', 'Y')";
$app->db->datalogInsert('spamfilter_users', $insert_data, 'id');
}
}else {
diff --git a/interface/web/sites/database_edit.php b/interface/web/sites/database_edit.php
index e066943..501c650 100644
--- a/interface/web/sites/database_edit.php
+++ b/interface/web/sites/database_edit.php
@@ -91,20 +91,6 @@
$tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = $client[default_webserver]");
$app->tpl->setVar("server_id","<option value='$client[default_webserver]'>$tmp[server_name]</option>");
unset($tmp);
-
- // Fill the client select field
- $sql = "SELECT groupid, name FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$client['client_id']." ORDER BY name";
- $clients = $app->db->queryAllRecords($sql);
- $tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ".$client['client_id']);
- $client_select = '<option value="'.$tmp['groupid'].'">'.$client['contact_name'].'</option>';
- //$tmp_data_record = $app->tform->getDataRecord($this->id);
- if(is_array($clients)) {
- foreach( $clients as $client) {
- $selected = @(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':'';
- $client_select .= "<option value='$client[groupid]' $selected>$client[name]</option>\r\n";
- }
- }
- $app->tpl->setVar("client_group_id",$client_select);
} else {
@@ -116,33 +102,6 @@
$tmp = $app->db->queryOneRecord("SELECT server_id FROM server WHERE web_server = 1 ORDER BY server_name LIMIT 0,1");
$server_id = $tmp['server_id'];
}
-
- $sql = "SELECT ip_address FROM server_ip WHERE server_id = $server_id";
- $ips = $app->db->queryAllRecords($sql);
- $ip_select = "<option value='*'>*</option>";
- //$ip_select = "";
- if(is_array($ips)) {
- foreach( $ips as $ip) {
- $selected = ($ip["ip_address"] == $this->dataRecord["ip_address"])?'SELECTED':'';
- $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n";
- }
- }
- $app->tpl->setVar("ip_address",$ip_select);
- unset($tmp);
- unset($ips);
-
- // Fill the client select field
- $sql = "SELECT groupid, name FROM sys_group WHERE client_id > 0 ORDER BY name";
- $clients = $app->db->queryAllRecords($sql);
- $client_select = "<option value='0'></option>";
- //$tmp_data_record = $app->tform->getDataRecord($this->id);
- if(is_array($clients)) {
- foreach( $clients as $client) {
- $selected = @(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':'';
- $client_select .= "<option value='$client[groupid]' $selected>$client[name]</option>\r\n";
- }
- }
- $app->tpl->setVar("client_group_id",$client_select);
}
@@ -212,9 +171,6 @@
}
}
-
- // Clients may not set the client_group_id, so we unset them if user is not a admin and the client is not a reseller
- if(!$app->auth->has_clients($_SESSION['s']['user']['userid'])) unset($this->dataRecord["client_group_id"]);
}
@@ -224,10 +180,8 @@
function onBeforeUpdate() {
global $app, $conf, $interfaceConf;
- /*
- * If the names should be restricted -> do it!
- */
-
+ //* Site shell not be empty
+ if($this->dataRecord['parent_domain_id'] == 0) $app->tform->errorMessage .= $app->tform->lng("database_site_error_empty").'<br />';
//* Get the database name and database user prefix
$app->uses('getconf');
@@ -290,6 +244,9 @@
function onBeforeInsert() {
global $app, $conf, $interfaceConf;
+ //* Site shell not be empty
+ if($this->dataRecord['parent_domain_id'] == 0) $app->tform->errorMessage .= $app->tform->lng("database_site_error_empty").'<br />';
+
//* Database username and database name shall not be empty
if($this->dataRecord['database_name'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_name_error_empty"].'<br />';
if($this->dataRecord['database_user'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_user_error_empty"].'<br />';
@@ -330,31 +287,33 @@
function onAfterInsert() {
global $app, $conf;
-
- // make sure that the record belongs to the clinet group and not the admin group when a dmin inserts it
- // also make sure that the user can not delete domain created by a admin
- if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) {
- $client_group_id = intval($this->dataRecord["client_group_id"]);
- $app->db->query("UPDATE web_database SET sys_groupid = $client_group_id, sys_perm_group = 'ru' WHERE database_id = ".$this->id);
- }
- if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) {
- $client_group_id = intval($this->dataRecord["client_group_id"]);
- $app->db->query("UPDATE web_database SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_id = ".$this->id);
+
+ if($this->dataRecord["parent_domain_id"] > 0) {
+ $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($this->dataRecord["parent_domain_id"]));
+
+ //* The Database user shall be owned by the same group then the website
+ $sys_groupid = $web['sys_groupid'];
+ $backup_interval = $web['backup_interval'];
+ $backup_copies = $web['backup_copies'];
+
+ $sql = "UPDATE web_database SET sys_groupid = '$sys_groupid', backup_interval = '$backup_interval', backup_copies = '$backup_copies' WHERE database_id = ".$this->id;
+ $app->db->query($sql);
}
}
function onAfterUpdate() {
global $app, $conf;
- // make sure that the record belongs to the client group and not the admin group when a admin inserts it
- // also make sure that the user can not delete domain created by a admin
- if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) {
- $client_group_id = intval($this->dataRecord["client_group_id"]);
- $app->db->query("UPDATE web_database SET sys_groupid = $client_group_id, sys_perm_group = 'ru' WHERE database_id = ".$this->id);
- }
- if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) {
- $client_group_id = intval($this->dataRecord["client_group_id"]);
- $app->db->query("UPDATE web_database SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_id = ".$this->id);
+ if($this->dataRecord["parent_domain_id"] > 0) {
+ $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($this->dataRecord["parent_domain_id"]));
+
+ //* The Database user shall be owned by the same group then the website
+ $sys_groupid = $web['sys_groupid'];
+ $backup_interval = $web['backup_interval'];
+ $backup_copies = $web['backup_copies'];
+
+ $sql = "UPDATE web_database SET sys_groupid = '$sys_groupid', backup_interval = '$backup_interval', backup_copies = '$backup_copies' WHERE database_id = ".$this->id;
+ $app->db->query($sql);
}
}
diff --git a/interface/web/sites/form/database.tform.php b/interface/web/sites/form/database.tform.php
index ffb711f..9bef109 100644
--- a/interface/web/sites/form/database.tform.php
+++ b/interface/web/sites/form/database.tform.php
@@ -69,6 +69,17 @@
),
'value' => ''
),
+ 'parent_domain_id' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => "SELECT domain_id,domain FROM web_domain WHERE type = 'vhost' AND {AUTHSQL} ORDER BY domain",
+ 'keyfield'=> 'domain_id',
+ 'valuefield'=> 'domain'
+ ),
+ 'value' => array('0' => $app->tform->lng('select_site_txt'))
+ ),
'type' => array (
'datatype' => 'VARCHAR',
'formtype' => 'SELECT',
diff --git a/interface/web/sites/form/web_domain.tform.php b/interface/web/sites/form/web_domain.tform.php
index 34cbbc8..241e6ea 100644
--- a/interface/web/sites/form/web_domain.tform.php
+++ b/interface/web/sites/form/web_domain.tform.php
@@ -431,7 +431,7 @@
)
);
-if($_SESSION["s"]["user"]["typ"] == 'admin') {
+// if($_SESSION["s"]["user"]["typ"] == 'admin') {
//* Backup
$form["tabs"]['backup'] = array (
@@ -458,10 +458,17 @@
##################################
# ENDE Datatable fields
##################################
+ ),
+ 'plugins' => array (
+ 'backup_records' => array (
+ 'class' => 'plugin_backuplist',
+ 'options' => array(
+ )
+ )
)
);
-}
+// }
if($_SESSION["s"]["user"]["typ"] == 'admin') {
diff --git a/interface/web/sites/lib/lang/en_database.lng b/interface/web/sites/lib/lang/en_database.lng
index 48d7ea3..abf302e 100644
--- a/interface/web/sites/lib/lang/en_database.lng
+++ b/interface/web/sites/lib/lang/en_database.lng
@@ -22,4 +22,9 @@
$wb["database_charset_change_txt"] = 'The database charset can not be changed';
$wb["database_name_error_len"] = 'Database name - {db} - too long. The max. database name length incl. prefix is 64 chars.';
$wb["database_user_error_len"] = 'Database username - {user}- too long. The max. database username length incl. prefix is 16 chars.';
+$wb["parent_domain_id_txt"] = 'Site';
+$wb["database_site_error_empty"] = 'Select the site to which the database belongs.';
+$wb["select_site_txt"] = '- Select Site -';
+$wb["btn_save_txt"] = 'Save';
+$wb["btn_cancel_txt"] = 'Cancel';
?>
diff --git a/interface/web/sites/lib/lang/en_web_backup_list.lng b/interface/web/sites/lib/lang/en_web_backup_list.lng
new file mode 100644
index 0000000..1ac6687
--- /dev/null
+++ b/interface/web/sites/lib/lang/en_web_backup_list.lng
@@ -0,0 +1,16 @@
+<?php
+$wb['list_head_txt'] = 'Existing backups';
+$wb['date_txt'] = 'Date';
+$wb['backup_type_txt'] = 'Type';
+$wb['filename_txt'] = 'Backup file';
+$wb['restore_backup_txt'] = 'Restore backup';
+$wb['download_backup_txt'] = 'Download backup';
+$wb['download_info_txt'] = 'The backup file will be available for download in the backup folder of the website in a few minutes.';
+$wb['restore_info_txt'] = 'Restore of the backup has been started. This action takes several minutes to be completed.';
+$wb['restore_confirm_txt'] = 'Restoring will overwrite existing files in your website. Do you really want to restore this backup?';
+$wb['download_pending_txt'] = 'There is already a pending backup download job.';
+$wb['restore_pending_txt'] = 'There is already a pending backup restore job.';
+$wb['backup_type_mysql'] = 'MySQL Database';
+$wb['backup_type_web'] = 'Website files';
+
+?>
\ No newline at end of file
diff --git a/interface/web/sites/templates/database_edit.htm b/interface/web/sites/templates/database_edit.htm
index 99e1d07..59b1bff 100644
--- a/interface/web/sites/templates/database_edit.htm
+++ b/interface/web/sites/templates/database_edit.htm
@@ -20,21 +20,13 @@
</select>
</tmpl_if>
</div>
- <div class="ctrlHolder">
- <label for="client_group_id">{tmpl_var name='client_txt'}</label>
- <select name="client_group_id" id="client_group_id" class="selectInput">
- {tmpl_var name='client_group_id'}
- </select>
- </div>
</tmpl_if>
- <tmpl_if name="is_reseller">
- <div class="ctrlHolder">
- <label for="client_group_id">{tmpl_var name='client_txt'}</label>
- <select name="client_group_id" id="client_group_id" class="selectInput">
- {tmpl_var name='client_group_id'}
+ <div class="ctrlHolder">
+ <label for="parent_domain_id">{tmpl_var name='parent_domain_id_txt'}</label>
+ <select name="parent_domain_id" id="parent_domain_id" class="selectInput">
+ {tmpl_var name='parent_domain_id'}
</select>
- </div>
- </tmpl_if>
+ </div>
<div class="ctrlHolder">
<label for="type">{tmpl_var name='type_txt'}</label>
<select name="type" id="type" class="selectInput formLengthHalf">
diff --git a/interface/web/sites/templates/web_backup_list.htm b/interface/web/sites/templates/web_backup_list.htm
new file mode 100644
index 0000000..7d91c23
--- /dev/null
+++ b/interface/web/sites/templates/web_backup_list.htm
@@ -0,0 +1,40 @@
+<tmpl_if name="msg">
+ <div id="OKMsg"><p><tmpl_var name="msg"></p></div>
+</tmpl_if>
+<tmpl_if name="error">
+ <div id="errorMsg"><h3>ERROR</h3><ol><tmpl_var name="error"></ol></div>
+</tmpl_if>
+<h3><tmpl_var name="list_head_txt"></h3>
+ <div class="pnl_listarea">
+ <fieldset><legend><tmpl_var name="list_head_txt"></legend>
+ <table class="list">
+ <thead>
+ <tr>
+ <th class="tbl_col_date" scope="col"><tmpl_var name="date_txt"></th>
+ <th class="tbl_col_date" scope="col"><tmpl_var name="backup_type_txt"></th>
+ <th class="tbl_col_filename" scope="col"><tmpl_var name="filename_txt"></th>
+ <th class="tbl_col_buttons" scope="col"> </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tmpl_loop name="records">
+ <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+ <td class="tbl_col_date">{tmpl_var name="date"}</td>
+ <td class="tbl_col_date">{tmpl_var name="backup_type"}</td>
+ <td class="tbl_col_filename">{tmpl_var name="filename"}</td>
+ <td class="tbl_col_buttons" style="width:300px;">
+ <div class="buttons" >
+ <button class="iconstxt icoRestore" type="button" onClick="confirm_action('sites/web_domain_edit.php?id={tmpl_var name='parent_id'}&next_tab=backup&backup_action=restore&backup_id={tmpl_var name='backup_id'}','{tmpl_var name='restore_confirm_txt'}');">
+ <span>{tmpl_var name="restore_backup_txt"}</span>
+ </button>
+ <button class="iconstxt icoDownload" type="button" onClick="loadContent('sites/web_domain_edit.php?id={tmpl_var name='parent_id'}&next_tab=backup&backup_action=download&backup_id={tmpl_var name='backup_id'}');">
+ <span>{tmpl_var name="download_backup_txt"}</span>
+ </button>
+ </div>
+ </td>
+ </tr>
+ </tmpl_loop>
+ </tbody>
+ </table>
+ </fieldset>
+ </div>
diff --git a/interface/web/sites/templates/web_domain_backup.htm b/interface/web/sites/templates/web_domain_backup.htm
index 6b8c627..14e3a8f 100644
--- a/interface/web/sites/templates/web_domain_backup.htm
+++ b/interface/web/sites/templates/web_domain_backup.htm
@@ -18,6 +18,8 @@
</select>
</div>
</fieldset>
+
+ {tmpl_var name='backup_records'}
<input type="hidden" name="id" value="{tmpl_var name='id'}">
diff --git a/interface/web/sites/tools.inc.php b/interface/web/sites/tools.inc.php
index 38e8804..316abe6 100644
--- a/interface/web/sites/tools.inc.php
+++ b/interface/web/sites/tools.inc.php
@@ -96,7 +96,7 @@
}
}
/* get the name of the client */
- $tmp = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = " . $client_group_id);
+ $tmp = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = " . intval($client_group_id));
$clientID = $tmp['client_id'];
if ($clientID == '') $clientID = '0';
return $clientID;
diff --git a/interface/web/sites/web_domain_del.php b/interface/web/sites/web_domain_del.php
index a69923f..f84f4f1 100644
--- a/interface/web/sites/web_domain_del.php
+++ b/interface/web/sites/web_domain_del.php
@@ -91,6 +91,12 @@
$app->db->datalogDelete('webdav_user','webdav_user_id',$rec['webdav_user_id']);
}
+ //* Delete all records that belog to this web
+ $records = $app->db->queryAllRecords("SELECT backup_id FROM web_backup WHERE parent_domain_id = '".intval($this->id)."'");
+ foreach($records as $rec) {
+ $app->db->datalogDelete('web_backup','backup_id',$rec['backup_id']);
+ }
+
//* Delete all web folders
$records = $app->db->queryAllRecords("SELECT web_folder_id FROM web_folder WHERE parent_domain_id = '".intval($this->id)."'");
foreach($records as $rec) {
diff --git a/interface/web/sites/web_domain_edit.php b/interface/web/sites/web_domain_edit.php
index b6236bd..91b965c 100644
--- a/interface/web/sites/web_domain_edit.php
+++ b/interface/web/sites/web_domain_edit.php
@@ -607,6 +607,14 @@
}
unset($records);
unset($rec);
+
+ //* Update all databases
+ $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ".$this->id);
+ foreach($records as $rec) {
+ $app->db->datalogUpdate('web_database', "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."'", 'database_id', $rec['database_id']);
+ }
+ unset($records);
+ unset($rec);
}
@@ -638,6 +646,21 @@
$sql = "UPDATE web_domain SET php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id;
$app->db->query($sql);
}
+
+ //* Change database backup options when web backup options have been changed
+ if(isset($this->dataRecord['backup_interval']) && ($this->dataRecord['backup_interval'] != $this->oldDataRecord['backup_interval'] || $this->dataRecord['backup_copies'] != $this->oldDataRecord['backup_copies'])) {
+ //* Update all databases
+ $backup_interval = $this->dataRecord['backup_interval'];
+ $backup_copies = $this->dataRecord['backup_copies'];
+ $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ".$this->id);
+ foreach($records as $rec) {
+ $app->db->datalogUpdate('web_database', "backup_interval = '$backup_interval', backup_copies = '$backup_copies'", 'database_id', $rec['database_id']);
+ }
+ unset($records);
+ unset($rec);
+ unset($backup_copies);
+ unset($backup_interval);
+ }
}
diff --git a/interface/web/themes/default/css/screen/content_ispc.css b/interface/web/themes/default/css/screen/content_ispc.css
index 9f53502..9e65bd4 100644
--- a/interface/web/themes/default/css/screen/content_ispc.css
+++ b/interface/web/themes/default/css/screen/content_ispc.css
@@ -366,6 +366,8 @@
.iconstxt.icoAdd { background-image: url(../../icons/x16/plus_circle_frame.png); }
.iconstxt.icoKey { background-image: url("../../icons/x16/key.png"); }
.iconstxt.icoDelete { background-image: url("../../icons/x16/minus_circle_frame.png"); }
+ .iconstxt.icoDownload { background-image: url("../../icons/x16/arrow_270.png"); }
+ .iconstxt.icoRestore { background-image: url("../../icons/x16/arrow_circle_225.png"); }
/* Button with icon and without text */
.icons16 span { display: none; }
diff --git a/server/cron_daily.php b/server/cron_daily.php
index 67d9945..87ba2ee 100644
--- a/server/cron_daily.php
+++ b/server/cron_daily.php
@@ -1,7 +1,7 @@
<?php
/*
-Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Copyright (c) 2007-2012, Till Brehm, projektfarm Gmbh
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -480,6 +480,11 @@
$server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
$backup_dir = $server_config['backup_dir'];
+$backup_mode = $server_config['backup_mode'];
+if($backup_mode == '') $backup_mode = 'userzip';
+
+$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
+$http_server_user = $web_config['user'];
if($backup_dir != '') {
@@ -495,12 +500,12 @@
chmod(escapeshellcmd($backup_dir), $backup_dir_permissions);
}
- $sql = "SELECT * FROM web_domain WHERE type = 'vhost'";
+ $sql = "SELECT * FROM web_domain WHERE server_id = '".$conf['server_id']."' AND type = 'vhost' AND backup_interval != 'none'";
$records = $app->db->queryAllRecords($sql);
if(is_array($records)) {
foreach($records as $rec) {
- // Create a backup
+ //* Do the website backup
if($rec['backup_interval'] == 'daily' or ($rec['backup_interval'] == 'weekly' && date('w') == 0) or ($rec['backup_interval'] == 'monthly' && date('d') == '01')) {
$web_path = $rec['document_root'];
@@ -510,46 +515,71 @@
$web_backup_dir = $backup_dir.'/web'.$web_id;
if(!is_dir($web_backup_dir)) mkdir($web_backup_dir, 0750);
chmod($web_backup_dir, 0750);
- if(isset($server_config['backup_dir_ftpread']) && $server_config['backup_dir_ftpread'] == 'y') {
- chown($web_backup_dir, $rec['system_user']);
- chgrp($web_backup_dir, $rec['system_group']);
- } else {
+ //if(isset($server_config['backup_dir_ftpread']) && $server_config['backup_dir_ftpread'] == 'y') {
+ chown($web_backup_dir, $rec['system_user']);
+ chgrp($web_backup_dir, $rec['system_group']);
+ /*} else {
chown($web_backup_dir, 'root');
chgrp($web_backup_dir, 'root');
+ }*/
+ if($backup_mode == 'userzip') {
+ //* Create a .zip backup as web user and include also files owned by apache / nginx user
+ $web_backup_file = 'web'.$web_id.'_'.date('Y-m-d_H-i').'.zip';
+ exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -group '.escapeshellarg($web_group).' -print 2> /dev/null | zip --exclude=backup\* --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@');
+ exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -user '.escapeshellarg($http_server_user).' -print 2> /dev/null | zip --exclude=backup\* --update --symlinks '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' -@');
+ } else {
+ //* Create a tar.gz backup as root user
+ $web_backup_file = 'web'.$web_id.'_'.date('Y-m-d_H-i').'.tar.gz';
+ exec('tar pczf '.escapeshellarg($web_backup_dir.'/'.$web_backup_file).' --exclude=backup\* --directory '.escapeshellarg($web_path).' .');
}
- exec('cd '.escapeshellarg($web_path).' && sudo -u '.escapeshellarg($web_user).' find . -group '.escapeshellarg($web_group).' -print | zip -y '.escapeshellarg($web_backup_dir.'/web.zip').' -@');
- chown($web_backup_dir.'/web.zip', $rec['system_user']);
- chgrp($web_backup_dir.'/web.zip', $rec['system_group']);
- chmod($web_backup_dir.'/web.zip', 0750);
+ chown($web_backup_dir.'/'.$web_backup_file, 'root');
+ chgrp($web_backup_dir.'/'.$web_backup_file, 'root');
+ chmod($web_backup_dir.'/'.$web_backup_file, 0750);
- // Rename or remove old backups
+ //* Insert web backup record in database
+ $insert_data = "(server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",".$web_id.",'web','".$backup_mode."',".time().",'".$app->db->quote($web_backup_file)."')";
+ $app->dbmaster->datalogInsert('web_backup', $insert_data, 'backup_id');
+
+ //* Remove old backups
$backup_copies = intval($rec['backup_copies']);
- //* delete any older backup copies that previously existed
- for ($n = $backup_copies; $n <= 10; $n++) {
- if(is_file($web_backup_dir.'/web.'.$n.'.zip')) unlink($web_backup_dir.'/web.'.$n.'.zip');
- }
-
- for($n = $backup_copies - 1; $n >= 1; $n--) {
- if(is_file($web_backup_dir.'/web.'.$n.'.zip')) {
- rename($web_backup_dir.'/web.'.$n.'.zip',$web_backup_dir.'/web.'.($n+1).'.zip');
+ $dir_handle = dir($web_backup_dir);
+ $files = array();
+ while (false !== ($entry = $dir_handle->read())) {
+ if($entry != '.' && $entry != '..' && substr($entry,0,3) == 'web' && is_file($web_backup_dir.'/'.$entry)) {
+ $files[] = $entry;
}
}
-
- if(is_file($web_backup_dir.'/web.zip')) rename($web_backup_dir.'/web.zip',$web_backup_dir.'/web.1.zip');
-
- // Create backupdir symlink
- if(is_link($web_path.'/backup')) unlink($web_path.'/backup');
- symlink($web_backup_dir,$web_path.'/backup');
- // chmod($web_path.'/backup', 0755);
- chown($web_path.'/backup', $rec['system_user']);
- chgrp($web_path.'/backup', $rec['system_group']);
+ $dir_handle->close();
+
+ rsort($files);
+
+ for ($n = $backup_copies; $n <= 10; $n++) {
+ if(isset($files[$n]) && is_file($web_backup_dir.'/'.$files[$n])) {
+ unlink($web_backup_dir.'/'.$files[$n]);
+ $sql = "SELECT backup_id FROM web_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = $web_id AND filename = '".$app->db->quote($files[$n])."'";
+ $tmp = $app->dbmaster->queryOneRecord($sql);
+ $app->dbmaster->datalogDelete('web_backup', 'backup_id', $tmp['backup_id']);
+ }
+ }
+
+ unset($files);
+ unset($dir_handle);
+
+ //* Remove backupdir symlink and create as directory instead
+ if(is_link($web_path.'/backup')) {
+ unlink($web_path.'/backup');
+ }
+ if(!is_dir($web_path.'/backup')) {
+ mkdir($web_path.'/backup');
+ chown($web_path.'/backup', $rec['system_user']);
+ chgrp($web_path.'/backup', $rec['system_group']);
+ }
}
/* If backup_interval is set to none and we have a
backup directory for the website, then remove the backups */
-
if($rec['backup_interval'] == 'none') {
$web_id = $rec['domain_id'];
$web_user = $rec['system_user'];
@@ -560,6 +590,78 @@
}
}
}
+
+ $sql = "SELECT * FROM web_database WHERE server_id = '".$conf['server_id']."' AND backup_interval != 'none'";
+ $records = $app->db->queryAllRecords($sql);
+ if(is_array($records)) {
+
+ include('lib/mysql_clientdb.conf');
+
+ foreach($records as $rec) {
+
+ //* Do the database backup
+ if($rec['backup_interval'] == 'daily' or ($rec['backup_interval'] == 'weekly' && date('w') == 0) or ($rec['backup_interval'] == 'monthly' && date('d') == '01')) {
+
+ $web_id = $rec['parent_domain_id'];
+ $db_backup_dir = $backup_dir.'/web'.$web_id;
+ if(!is_dir($web_backup_dir)) mkdir($web_backup_dir, 0750);
+ chmod($web_backup_dir, 0750);
+ chown($web_backup_dir, 'root');
+ chgrp($web_backup_dir, 'root');
+
+ //* Do the mysql database backup with mysqldump
+ $db_id = $rec['database_id'];
+ $db_name = $rec['database_name'];
+ $db_backup_file = 'db_'.$db_name.'_'.date('Y-m-d_H-i').'.sql';
+ $command = "mysqldump -h '".escapeshellcmd($clientdb_host)."' -u '".escapeshellcmd($clientdb_user)."' -p'".escapeshellcmd($clientdb_password)."' -c --add-drop-table --create-options --quick --result-file='".$db_backup_dir.'/'.$db_backup_file."' '".$db_name."'";
+ exec($command);
+
+ //* Compress the backup with gzip
+ exec("gzip -c '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file)."' > '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".gz'");
+ chmod($db_backup_dir.'/'.$db_backup_file.'.gz', 0750);
+ chown($db_backup_dir.'/'.$db_backup_file.'.gz', fileowner($db_backup_dir));
+ chgrp($db_backup_dir.'/'.$db_backup_file.'.gz', filegroup($db_backup_dir));
+
+ //* Insert web backup record in database
+ $insert_data = "(server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mysql','sqlgz',".time().",'".$app->db->quote($db_backup_file).".gz')";
+ $app->dbmaster->datalogInsert('web_backup', $insert_data, 'backup_id');
+
+ //* Remove the uncompressed file
+ unlink($db_backup_dir.'/'.$db_backup_file);
+
+ //* Remove old backups
+ $backup_copies = intval($rec['backup_copies']);
+
+ $dir_handle = dir($db_backup_dir);
+ $files = array();
+ while (false !== ($entry = $dir_handle->read())) {
+ if($entry != '.' && $entry != '..' && substr($entry,0,2) == 'db' && is_file($db_backup_dir.'/'.$entry)) {
+ $files[] = $entry;
+ }
+ }
+ $dir_handle->close();
+
+ rsort($files);
+
+ for ($n = $backup_copies; $n <= 10; $n++) {
+ if(isset($files[$n]) && is_file($db_backup_dir.'/'.$files[$n])) {
+ unlink($db_backup_dir.'/'.$files[$n]);
+ $sql = "SELECT backup_id FROM web_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = $web_id AND filename = '".$app->db->quote($files[$n])."'";
+ $tmp = $app->dbmaster->queryOneRecord($sql);
+ $app->dbmaster->datalogDelete('web_backup', 'backup_id', $tmp['backup_id']);
+ }
+ }
+
+ unset($files);
+ unset($dir_handle);
+ }
+ }
+
+ unset($clientdb_host);
+ unset($clientdb_user);
+ unset($clientdb_password);
+
+ }
}
diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php
index 18f09bf..54561c0 100644
--- a/server/lib/classes/db_mysql.inc.php
+++ b/server/lib/classes/db_mysql.inc.php
@@ -1,4 +1,3 @@
-
<?php
/*
Copyright (c) 2005, Till Brehm, projektfarm Gmbh
@@ -226,10 +225,10 @@
if(is_array($record_old) && count($record_old) > 0) {
foreach($record_old as $key => $val) {
// if(!isset($record_new[$key]) || $record_new[$key] != $val) {
- if($record_new[$key] != $val) {
+ if(@$record_new[$key] != $val) {
// Record has changed
$diffrec_full['old'][$key] = $val;
- $diffrec_full['new'][$key] = $record_new[$key];
+ $diffrec_full['new'][$key] = @$record_new[$key];
$diff_num++;
} else {
$diffrec_full['old'][$key] = $val;
@@ -593,4 +592,4 @@
}
- ?>
+ ?>
\ No newline at end of file
diff --git a/server/lib/classes/modules.inc.php b/server/lib/classes/modules.inc.php
index 2c5b349..ef600bd 100644
--- a/server/lib/classes/modules.inc.php
+++ b/server/lib/classes/modules.inc.php
@@ -229,8 +229,46 @@
$app->log('Processed datalog_id '.$d['datalog_id'],LOGLEVEL_DEBUG);
}
}
+ }
+
+ function processActions() {
+ global $app,$conf;
+ //* get the server_id of the local server
+ $server_id = intval($conf["server_id"]);
+ include_once (SCRIPT_PATH."/lib/remote_action.inc.php");
+
+ //* SQL query to get all pending actions
+ $sql = "SELECT action_id, action_type, action_param " .
+ "FROM sys_remoteaction " .
+ "WHERE server_id = " . $server_id . " ".
+ " AND action_id > " . intval($maxid_remote_action) . " ".
+ "ORDER BY action_id";
+
+ $actions = $app->dbmaster->queryAllRecords($sql);
+
+ if(is_array($actions)) {
+ foreach($actions as $action) {
+
+ //* Raise the action
+ $state = $app->plugins->raiseAction($action['action_type'],$action['action_param']);
+
+ //* Update the action state
+ $sql = "UPDATE sys_remoteaction " .
+ "SET action_state = '" . $app->dbmaster->quote($state) . "' " .
+ "WHERE action_id = " . intval($action['action_id']);
+ $app->dbmaster->query($sql);
+
+ /*
+ * Then save the maxid for the next time...
+ */
+ $fp = fopen(ISPC_LIB_PATH."/remote_action.inc.php", 'wb');
+ $content = '<?php' . "\n" . '$maxid_remote_action = ' . $action['action_id'] . ';' . "\n?>";
+ fwrite($fp, $content);
+ fclose($fp);
+ }
+ }
diff --git a/server/lib/classes/plugins.inc.php b/server/lib/classes/plugins.inc.php
index ba12981..afef438 100644
--- a/server/lib/classes/plugins.inc.php
+++ b/server/lib/classes/plugins.inc.php
@@ -1,7 +1,7 @@
<?php
/*
-Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Copyright (c) 2007-2012, Till Brehm, projektfarm Gmbh
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -32,6 +32,7 @@
var $available_events = array();
var $subscribed_events = array();
+ var $subscribed_actions = array();
var $debug = false;
/*
@@ -126,6 +127,45 @@
unset($events);
}
+ /*
+ This function is called by the plugin to register for an action
+ */
+
+ function registerAction($action_name,$plugin_name,$function_name) {
+ global $app;
+ $this->subscribed_actions[$action_name][] = array('plugin' => $plugin_name, 'function' => $function_name);
+ if($this->debug) $app->log("Registered function '$function_name' from plugin '$plugin_name' for action '$event_name'.",LOGLEVEL_DEBUG);
+ }
+
+
+ function raiseAction($action_name,$data) {
+ global $app;
+
+ //* Get the subscriptions for this action
+ $actions = (isset($this->subscribed_actions[$action_name]))?$this->subscribed_actions[$action_name]:'';
+ if($this->debug) $app->log('Raised action: '.$action_name,LOGLEVEL_DEBUG);
+
+ if(is_array($actions)) {
+ foreach($actions as $action) {
+ $plugin_name = $action['plugin'];
+ $function_name = $action['function'];
+ $state_out = 'ok';
+ //* Call the processing function of the plugin
+ $app->log("Calling function '$function_name' from plugin '$plugin_name' raised by action '$action_name'.",LOGLEVEL_DEBUG);
+ $state = call_user_func(array($app->loaded_plugins[$plugin_name],$function_name),$action_name,$data);
+ //* ensure that we return the highest warning / error level if a error occured in one of the functions
+ if($state == 'warning' && $state_out != 'error') $state_out = 'warning';
+ if($state == 'error') $state_out = 'error';
+ unset($plugin_name);
+ unset($function_name);
+ }
+ }
+ unset($action);
+ unset($actions);
+
+ return $state_out;
+ }
+
}
?>
diff --git a/server/mods-available/remoteaction_core_module.inc.php b/server/mods-available/remoteaction_core_module.inc.php
index 49294f4..5ee3fc6 100644
--- a/server/mods-available/remoteaction_core_module.inc.php
+++ b/server/mods-available/remoteaction_core_module.inc.php
@@ -1,6 +1,6 @@
<?php
/*
-Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh and Oliver Vogel www.muv.com
+Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh, Oliver Vogel www.muv.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -35,7 +35,7 @@
//* This function is called during ispconfig installation to determine
// if a symlink shall be created for this plugin.
function onInstall() {
- return true;
+ return false;
}
/*
@@ -45,7 +45,8 @@
/*
* Check for actions to execute
*/
- $this->_execActions();
+ //* This module has been replaced by the new action framework.
+ // $this->_execActions();
}
/*
diff --git a/server/mods-available/web_module.inc.php b/server/mods-available/web_module.inc.php
index 653940f..086b601 100644
--- a/server/mods-available/web_module.inc.php
+++ b/server/mods-available/web_module.inc.php
@@ -49,7 +49,10 @@
'web_folder_delete',
'web_folder_user_insert',
'web_folder_user_update',
- 'web_folder_user_delete');
+ 'web_folder_user_delete',
+ 'web_backup_insert',
+ 'web_backup_update',
+ 'web_backup_delete');
//* This function is called during ispconfig installation to determine
// if a symlink shall be created for this plugin.
@@ -94,6 +97,7 @@
$app->modules->registerTableHook('webdav_user','web_module','process');
$app->modules->registerTableHook('web_folder','web_module','process');
$app->modules->registerTableHook('web_folder_user','web_module','process');
+ $app->modules->registerTableHook('web_backup','web_module','process');
// Register service
$app->services->registerService('httpd','web_module','restartHttpd');
@@ -139,6 +143,11 @@
if($action == 'u') $app->plugins->raiseEvent('web_folder_user_update',$data);
if($action == 'd') $app->plugins->raiseEvent('web_folder_user_delete',$data);
break;
+ case 'web_backup':
+ if($action == 'i') $app->plugins->raiseEvent('web_backup_insert',$data);
+ if($action == 'u') $app->plugins->raiseEvent('web_backup_update',$data);
+ if($action == 'd') $app->plugins->raiseEvent('web_backup_delete',$data);
+ break;
} // end switch
} // end function
diff --git a/server/plugins-available/backup_plugin.inc.php b/server/plugins-available/backup_plugin.inc.php
new file mode 100644
index 0000000..dfe3ddd
--- /dev/null
+++ b/server/plugins-available/backup_plugin.inc.php
@@ -0,0 +1,134 @@
+<?php
+
+/*
+Copyright (c) 2012, Till Brehm, ISPConfig UG
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class backup_plugin {
+
+ var $plugin_name = 'backup_plugin';
+ var $class_name = 'backup_plugin';
+
+ //* This function is called during ispconfig installation to determine
+ // if a symlink shall be created for this plugin.
+ public function onInstall() {
+ global $conf;
+
+ return true;
+
+ }
+
+
+ /*
+ This function is called when the plugin is loaded
+ */
+
+ public function onLoad() {
+ global $app;
+
+ //* Register for actions
+ $app->plugins->registerAction('backup_download',$this->plugin_name,'backup_action');
+ $app->plugins->registerAction('backup_restore',$this->plugin_name,'backup_action');
+
+ }
+
+ //* Do a backup action
+ public function backup_action($action_name,$data) {
+ global $app,$conf;
+
+ $backup_id = intval($data);
+ $backup = $app->db->queryOneRecord("SELECT * FROM web_backup WHERE backup_id = $backup_id");
+
+ if(is_array($backup)) {
+
+ $app->uses('ini_parser,file,getconf');
+
+ $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$backup['parent_domain_id']);
+ $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
+ $backup_dir = $server_config['backup_dir'].'/web'.$web['domain_id'];
+
+ //* Make backup available for download
+ if($action_name == 'backup_download') {
+ //* Copy the backup file to the backup folder of the website
+ if(file_exists($backup_dir.'/'.$backup['filename']) && !stristr($backup_dir.'/'.$backup['filename'],'..') && !stristr($backup_dir.'/'.$backup['filename'],'etc')) {
+ copy($backup_dir.'/'.$backup['filename'],$web['document_root'].'/backup/'.$backup['filename']);
+ chgrp($web['document_root'].'/backup/'.$backup['filename'],$web['system_group']);
+ $app->log('cp '.$backup_dir.'/'.$backup['filename'].' '.$web['document_root'].'/backup/'.$backup['filename'],LOGLEVEL_DEBUG);
+ }
+ }
+
+ //* Restore a mysql backup
+ if($action_name == 'backup_restore' && $backup['backup_type'] == 'mysql') {
+ //* Load sql dump into db
+ include('lib/mysql_clientdb.conf');
+
+ if(file_exists($backup_dir.'/'.$backup['filename'])) {
+ $parts = explode('_',$backup['filename']);
+ $db_name = $parts[1];
+ $command = "gunzip --stdout ".escapeshellarg($backup_dir.'/'.$backup['filename'])." | mysql -h '".escapeshellcmd($clientdb_host)."' -u '".escapeshellcmd($clientdb_user)."' -p'".escapeshellcmd($clientdb_password)."' '".$db_name."'";
+ exec($command);
+ }
+ unset($clientdb_host);
+ unset($clientdb_user);
+ unset($clientdb_password);
+ $app->log('Restored MySQL backup '.$backup_dir.'/'.$backup['filename'],LOGLEVEL_DEBUG);
+ }
+
+ //* Restore a web backup
+ if($action_name == 'backup_restore' && $backup['backup_type'] == 'web') {
+ if($backup['backup_mode'] == 'userzip') {
+ if(file_exists($backup_dir.'/'.$backup['filename']) && $web['document_root'] != '' && $web['document_root'] != '/' && !stristr($backup_dir.'/'.$backup['filename'],'..') && !stristr($backup_dir.'/'.$backup['filename'],'etc')) {
+ if(file_exists($web['document_root'].'/backup/'.$backup['filename'])) rename($web['document_root'].'/backup/'.$backup['filename'],$web['document_root'].'/backup/'.$backup['filename'].'.bak');
+ copy($backup_dir.'/'.$backup['filename'],$web['document_root'].'/backup/'.$backup['filename']);
+ chgrp($web['document_root'].'/backup/'.$backup['filename'],$web['system_group']);
+ //chown($web['document_root'].'/backup/'.$backup['filename'],$web['system_user']);
+ $command = 'sudo -u '.escapeshellarg($web['system_user']).' unzip -qq -o '.escapeshellarg($web['document_root'].'/backup/'.$backup['filename']).' -d '.escapeshellarg($web['document_root']).' 2> /dev/null';
+ exec($command);
+ unlink($web['document_root'].'/backup/'.$backup['filename']);
+ if(file_exists($web['document_root'].'/backup/'.$backup['filename'].'.bak')) rename($web['document_root'].'/backup/'.$backup['filename'].'.bak',$web['document_root'].'/backup/'.$backup['filename']);
+ $app->log('Restored Web backup '.$backup_dir.'/'.$backup['filename'],LOGLEVEL_DEBUG);
+ }
+ }
+ if($backup['backup_mode'] == 'rootgz') {
+ if(file_exists($backup_dir.'/'.$backup['filename']) && $web['document_root'] != '' && $web['document_root'] != '/' && !stristr($backup_dir.'/'.$backup['filename'],'..') && !stristr($backup_dir.'/'.$backup['filename'],'etc')) {
+ $command = 'tar xzf '.escapeshellarg($backup_dir.'/'.$backup['filename']).' --directory '.escapeshellarg($web['document_root']);
+ exec($command);
+ $app->log('Restored Web backup '.$backup_dir.'/'.$backup['filename'],LOGLEVEL_DEBUG);
+ }
+ }
+ }
+
+ } else {
+ $app->log('No backup with ID '.$backup_id.' found.',LOGLEVEL_DEBUG);
+ }
+
+ return 'ok';
+ }
+
+} // end class
+
+?>
diff --git a/server/plugins-available/mysql_clientdb_plugin.inc.php b/server/plugins-available/mysql_clientdb_plugin.inc.php
index 624ef2b..59a6cf4 100644
--- a/server/plugins-available/mysql_clientdb_plugin.inc.php
+++ b/server/plugins-available/mysql_clientdb_plugin.inc.php
@@ -100,7 +100,7 @@
if($valid == false) continue;
if($action == 'GRANT') {
- if(!$link->query("GRANT ALL ON ".$link->escape_string($database_name,$link).".* TO '".$link->escape_string($database_user,$link)."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($database_password,$link)."';",$link)) $success = false;
+ if(!$link->query("GRANT ALL ON ".$link->escape_string($database_name).".* TO '".$link->escape_string($database_user)."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($database_password)."';")) $success = false;
} elseif($action == 'REVOKE') {
//mysql_query("REVOKE ALL PRIVILEGES ON ".mysql_real_escape_string($database_name,$link).".* FROM '".mysql_real_escape_string($database_user,$link)."';",$link);
} elseif($action == 'DROP') {
@@ -108,7 +108,7 @@
} elseif($action == 'RENAME') {
if(!$link->query("RENAME USER '".$link->escape_string($database_user)."'@'$db_host' TO '".$link->escape_string($database_rename_user)."'@'$db_host'")) $success = false;
} elseif($action == 'PASSWORD') {
- if(!$link->query("SET PASSWORD FOR '".$link->escape_string($database_user,$link)."'@'$db_host' = '".$link->escape_string($database_password,$link)."';",$link)) $success = false;
+ if(!$link->query("SET PASSWORD FOR '".$link->escape_string($database_user)."'@'$db_host' = '".$link->escape_string($database_password)."';")) $success = false;
}
}
@@ -158,7 +158,7 @@
}
$db_host = 'localhost';
- $link->query("GRANT ALL ON `".str_replace(array('_','%'),array('\\_','\\%'),$link->escape_string($data['new']['database_name'],$link))."`.* TO '".$link->escape_string($data['new']['database_user'],$link)."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($data['new']['database_password'],$link)."';",$link);
+ $link->query("GRANT ALL ON `".str_replace(array('_','%'),array('\\_','\\%'),$link->escape_string($data['new']['database_name']))."`.* TO '".$link->escape_string($data['new']['database_user'])."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($data['new']['database_password'])."';");
}
@@ -197,7 +197,7 @@
}
$db_host = 'localhost';
- $link->query("GRANT ALL ON `".str_replace(array('_','%'),array('\\_','\\%'),$link->escape_string($data['new']['database_name'],$link))."`.* TO '".$link->escape_string($data['new']['database_user'],$link)."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($data['new']['database_password'],$link)."';",$link);
+ $link->query("GRANT ALL ON `".str_replace(array('_','%'),array('\\_','\\%'),$link->escape_string($data['new']['database_name']))."`.* TO '".$link->escape_string($data['new']['database_user'])."'@'$db_host' IDENTIFIED BY PASSWORD '".$link->escape_string($data['new']['database_password'])."';");
// mysql_query("GRANT ALL ON ".mysql_real_escape_string($data["new"]["database_name"],$link).".* TO '".mysql_real_escape_string($data["new"]["database_user"],$link)."'@'$db_host' IDENTIFIED BY '".mysql_real_escape_string($data["new"]["database_password"],$link)."';",$link);
//echo "GRANT ALL ON ".mysql_real_escape_string($data["new"]["database_name"]).".* TO '".mysql_real_escape_string($data["new"]["database_user"])."'@'$db_host' IDENTIFIED BY '".mysql_real_escape_string($data["new"]["database_password"])."';";
@@ -247,10 +247,10 @@
//* Change password
if($data['new']['database_password'] != $data['old']['database_password']) {
$db_host = 'localhost';
- $link->query("SET PASSWORD FOR '".$link->escape_string($data['new']['database_user'],$link)."'@'$db_host' = '".$link->escape_string($data['new']['database_password'],$link)."';",$link);
+ $link->query("SET PASSWORD FOR '".$link->escape_string($data['new']['database_user'])."'@'$db_host' = '".$link->escape_string($data['new']['database_password'])."';");
if($data['new']['remote_access'] == 'y') {
- $this->process_host_list('PASSWORD', '', $data['new']['database_user'], $data['new']['database_password'], $data['new']['remote_ips']);
+ $this->process_host_list('PASSWORD', '', $data['new']['database_user'], $data['new']['database_password'], $data['new']['remote_ips'],$link);
}
$app->log('Changing MySQL user password for: '.$data['new']['database_user'],LOGLEVEL_DEBUG);
}
diff --git a/server/plugins-available/openvz_plugin.inc.php b/server/plugins-available/openvz_plugin.inc.php
index ac9e0aa..9e0d75d 100644
--- a/server/plugins-available/openvz_plugin.inc.php
+++ b/server/plugins-available/openvz_plugin.inc.php
@@ -1,7 +1,7 @@
<?php
/*
-Copyright (c) 2011, Till Brehm, projektfarm Gmbh
+Copyright (c) 2011-2012, Till Brehm, projektfarm Gmbh
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -63,6 +63,14 @@
$app->plugins->registerEvent('openvz_vm_insert',$this->plugin_name,'vm_insert');
$app->plugins->registerEvent('openvz_vm_update',$this->plugin_name,'vm_update');
$app->plugins->registerEvent('openvz_vm_delete',$this->plugin_name,'vm_delete');
+
+ //* Register for actions
+ $app->plugins->registerAction('openvz_start_vm',$this->plugin_name,'actions');
+ $app->plugins->registerAction('openvz_stop_vm',$this->plugin_name,'actions');
+ $app->plugins->registerAction('openvz_restart_vm',$this->plugin_name,'actions');
+ $app->plugins->registerAction('openvz_create_ostpl',$this->plugin_name,'actions');
+
+
}
@@ -149,6 +157,50 @@
}
+ function actions($action_name,$data) {
+ global $app, $conf;
+
+ if ($action_name == 'openvz_start_vm') {
+ $veid = intval($data);
+ if($veid > 0) {
+ exec("vzctl start $veid");
+ $app->log("Start VM: vzctl start $veid",LOGLEVEL_DEBUG);
+ }
+ return 'ok';
+ }
+ if ($action_name == 'openvz_stop_vm') {
+ $veid = intval($data);
+ if($veid > 0) {
+ exec("vzctl stop $veid");
+ $app->log("Stop VM: vzctl stop $veid",LOGLEVEL_DEBUG);
+ }
+ return 'ok';
+ }
+ if ($action_name == 'openvz_restart_vm') {
+ $veid = intval($data);
+ if($veid > 0) {
+ exec("vzctl restart $veid");
+ $app->log("Restart VM: vzctl restart $veid",LOGLEVEL_DEBUG);
+ }
+ return 'ok';
+ }
+ if ($action_name == 'openvz_create_ostpl') {
+ $parts = explode(':',$data);
+ $veid = intval($parts[0]);
+ $template_cache_dir = '/vz/template/cache/';
+ $template_name = escapeshellcmd($parts[1]);
+ if($veid > 0 && $template_name != '' && is_dir($template_cache_dir)) {
+ $command = "vzdump --suspend --compress --stdexcludes --dumpdir $template_cache_dir $veid";
+ exec($command);
+ exec("mv ".$template_cache_dir."vzdump-openvz-".$veid."*.tgz ".$template_cache_dir.$template_name.".tar.gz");
+ exec("rm -f ".$template_cache_dir."vzdump-openvz-".$veid."*.log");
+ }
+ $app->log("Created OpenVZ OStemplate $template_name from VM $veid",LOGLEVEL_DEBUG);
+ return 'ok';
+ }
+
+ }
+
} // end class
diff --git a/server/plugins-available/software_update_plugin.inc.php b/server/plugins-available/software_update_plugin.inc.php
index 55feaee..a6b7162 100644
--- a/server/plugins-available/software_update_plugin.inc.php
+++ b/server/plugins-available/software_update_plugin.inc.php
@@ -1,7 +1,7 @@
<?php
/*
-Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Copyright (c) 2007-2012, Till Brehm, projektfarm Gmbh, Oliver Vogel www.muv.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -35,7 +35,7 @@
//* This function is called during ispconfig installation to determine
// if a symlink shall be created for this plugin.
- function onInstall() {
+ public function onInstall() {
global $conf;
return true;
@@ -47,29 +47,31 @@
This function is called when the plugin is loaded
*/
- function onLoad() {
+ public function onLoad() {
global $app;
/*
Register for the events
*/
- //* Mailboxes
$app->plugins->registerEvent('software_update_inst_insert',$this->plugin_name,'process');
//$app->plugins->registerEvent('software_update_inst_update',$this->plugin_name,'process');
//$app->plugins->registerEvent('software_update_inst_delete',$this->plugin_name,'process');
+ //* Register for actions
+ $app->plugins->registerAction('os_update',$this->plugin_name,'os_update');
+
}
- function set_install_status($inst_id, $status) {
+ private function set_install_status($inst_id, $status) {
global $app;
$app->db->query("UPDATE software_update_inst SET status = '{$status}' WHERE software_update_inst_id = '{$inst_id}'");
$app->dbmaster->query("UPDATE software_update_inst SET status = '{$status}' WHERE software_update_inst_id = '{$inst_id}'");
}
- function process($event_name,$data) {
+ public function process($event_name,$data) {
global $app, $conf;
//* Get the info of the package:
@@ -271,6 +273,26 @@
}
}
+
+ //* Operating system update
+ public function os_update($action_name,$data) {
+ global $app;
+
+ //** Debian and compatible Linux distributions
+ if(file_exists('/etc/debian_version')) {
+ exec("aptitude update");
+ exec("aptitude safe-upgrade -y");
+ $app->log('Execeuted Debian / Ubuntu update',LOGLEVEL_DEBUG);
+ }
+
+ //** Gentoo Linux
+ if(file_exists('/etc/gentoo-release')) {
+ exec("glsa-check -f --nocolor affected");
+ $app->log('Execeuted Gentoo update',LOGLEVEL_DEBUG);
+ }
+
+ return 'ok';
+ }
} // end class
diff --git a/server/server.php b/server/server.php
index 869a621..3683f19 100644
--- a/server/server.php
+++ b/server/server.php
@@ -144,27 +144,26 @@
$tmp_num_records = $tmp_rec['number'];
unset($tmp_rec);
-
+
+ //** Load required base-classes
+ $app->uses('modules,plugins,file,services');
+ //** Load the modules that are in the mods-enabled folder
+ $app->modules->loadModules('all');
+ //** Load the plugins that are in the plugins-enabled folder
+ $app->plugins->loadPlugins('all');
if ($tmp_num_records > 0) {
- /*
- There is something to do, triggert by the database -> do it!
- */
- // Write the Log
$app->log("Found $tmp_num_records changes, starting update process.", LOGLEVEL_DEBUG);
- // Load required base-classes
- $app->uses('modules,plugins,file,services');
- // Load the modules that are in the mods-enabled folder
- $app->modules->loadModules('all');
- // Load the plugins that are in the plugins-enabled folder
- $app->plugins->loadPlugins('all');
- // Go through the sys_datalog table and call the processing functions
- // from the modules that are hooked on to the table actions
+ //** Go through the sys_datalog table and call the processing functions
+ //** from the modules that are hooked on to the table actions
$app->modules->processDatalog();
- // Restart services that need to after configuration
- $app->services->processDelayedActions();
- // All modules are already loaded and processed, so there is NO NEED to load the core once again...
- $needStartCore = false;
}
+ //** Process actions from sys_remoteaction table
+ $app->modules->processActions();
+ //** Restart services that need to after configuration
+ $app->services->processDelayedActions();
+ //** All modules are already loaded and processed, so there is NO NEED to load the core once again...
+ $needStartCore = false;
+
} else {
if ($app->db->connect->connect_error == NULL) {
$app->log('Unable to connect to local server.' . $app->db->errorMessage, LOGLEVEL_WARN);
--
Gitblit v1.9.1