tbrehm
2012-01-04 5c38f2cb6efe14ec205f6b312d057bbba3d98e02
commit | author | age
48ced1 1 <?php
T 2
3 /*
436ed8 4 Copyright (c) 2007, Till Brehm, projektfarm Gmbh
48ced1 5 All rights reserved.
T 6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 class software_update_plugin {
32     
33     var $plugin_name = 'software_update_plugin';
34     var $class_name  = 'software_update_plugin';
35     
392450 36     //* This function is called during ispconfig installation to determine
T 37     //  if a symlink shall be created for this plugin.
38     function onInstall() {
39         global $conf;
40         
41         return true;
42         
43     }
44     
48ced1 45         
T 46     /*
47          This function is called when the plugin is loaded
48     */
49     
50     function onLoad() {
51         global $app;
52         
53         /*
54         Register for the events
55         */
56         
57         //* Mailboxes
58         $app->plugins->registerEvent('software_update_inst_insert',$this->plugin_name,'process');
59         //$app->plugins->registerEvent('software_update_inst_update',$this->plugin_name,'process');
60         //$app->plugins->registerEvent('software_update_inst_delete',$this->plugin_name,'process');
61         
62         
63     }
64     
086696 65     function set_install_status($inst_id, $status) {
M 66         global $app;
67         
68         $app->db->query("UPDATE software_update_inst SET status = '{$status}' WHERE software_update_inst_id = '{$inst_id}'");
69         $app->dbmaster->query("UPDATE software_update_inst SET status = '{$status}' WHERE software_update_inst_id = '{$inst_id}'");
70     }
71     
48ced1 72     function process($event_name,$data) {
T 73         global $app, $conf;
74         
df8a46 75         //* Get the info of the package:
8e725d 76         $software_update_id = intval($data["new"]["software_update_id"]);
df8a46 77         $software_update = $app->db->queryOneRecord("SELECT * FROM software_update WHERE software_update_id = '$software_update_id'");
T 78         $software_package = $app->db->queryOneRecord("SELECT * FROM software_package WHERE package_name = '".$app->db->quote($software_update['package_name'])."'");
79         
80         if($software_package['package_type'] == 'ispconfig' && !$conf['software_updates_enabled'] == true) {
81             $app->log('Software Updates not enabled on this server. To enable updates, set $conf["software_updates_enabled"] = true; in config.inc.php',LOGLEVEL_WARN);
086696 82             $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
48ced1 83             return false;
T 84         }
85         
df8a46 86         $installuser = '';
T 87         if($software_package['package_type'] == 'ispconfig') {
88             $installuser = '';
89         } elseif ($software_package['package_type'] == 'app') {
90             $installuser = 'ispapps';
91         } else {
92             $app->log('package_type not supported',LOGLEVEL_WARN);
93             $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
94             return false;
95         }
48ced1 96         
T 97         $temp_dir = '/tmp/'.md5 (uniqid (rand()));
98         $app->log("The temp dir is $temp_dir",LOGLEVEL_DEBUG);
99         mkdir($temp_dir);
8e725d 100         if($installuser != '') chown($temp_dir, $installuser);
df8a46 101         
48ced1 102         if(!is_dir($temp_dir)) {
df8a46 103             $app->log("Unable to create temp directory.",LOGLEVEL_WARN);
086696 104             $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
48ced1 105             return false;
T 106         }
107         
1390c8 108         //* Replace placeholders in download URL
T 109         $software_update["update_url"] = str_replace('{key}',$software_package['package_key'],$software_update["update_url"]);
110         
111         //* Download the update package
df8a46 112         $cmd = "cd $temp_dir && wget ".$software_update["update_url"];
T 113         if($installuser == '') {
114             exec($cmd);
115         } else {
116             exec("su -c ".escapeshellarg($cmd)." $installuser");
117         }
48ced1 118         $app->log("Downloading the update file from: ".$software_update["update_url"],LOGLEVEL_DEBUG);
T 119         
1390c8 120         //$url_parts = parse_url($software_update["update_url"]);
T 121         //$update_filename = basename($url_parts["path"]);
122         //* Find the name of the zip file which contains the app.
123         $tmp_dir_handle = dir($temp_dir);
124         $update_filename = '';
125         while (false !== ($t = $tmp_dir_handle->read())) {
126             if($t != '.' && $t != '..' && is_file($temp_dir.'/'.$t) && substr($t,-4) == '.zip') {
127                 $update_filename = $t;
128             }
129         }
130         $tmp_dir_handle->close();
131         unset($tmp_dir_handle);
132         unset($t);
133         
134         if($update_filename == '') {
135             $app->log("No package file found. Download failed? Installation aborted.",LOGLEVEL_WARN);
136             exec("rm -rf $temp_dir");
137             $app->log("Deleting the temp directory $temp_dir",LOGLEVEL_DEBUG);
8e725d 138             $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
1390c8 139             return false;
T 140         }
141
48ced1 142         $app->log("The update filename is $update_filename",LOGLEVEL_DEBUG);
T 143         
144         if(is_file($temp_dir.'/'.$update_filename)) {
145             
146             //* Checking the md5sum
147             if(md5_file($temp_dir.'/'.$update_filename) != $software_update["update_md5"]) {
df8a46 148                 $app->log("The md5 sum of the downloaded file is incorrect. Update aborted.",LOGLEVEL_WARN);
48ced1 149                 exec("rm -rf $temp_dir");
T 150                 $app->log("Deleting the temp directory $temp_dir",LOGLEVEL_DEBUG);
8e725d 151                 $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
48ced1 152                 return false;
3f133e 153             } else {
8e725d 154                 $app->log("MD5 checksum of the downloaded file verified.",LOGLEVEL_DEBUG);
48ced1 155             }
T 156             
157             
158             //* unpacking the update
df8a46 159             $cmd = "cd $temp_dir && unzip $update_filename";
T 160             if($installuser == '') {
161                 exec($cmd);
162             } else {
163                 exec("su -c ".escapeshellarg($cmd)." $installuser");
1390c8 164             }
T 165             
166             //* Create a database, if the package requires one
167             if($software_package['package_type'] == 'app' && $software_package['package_requires_db'] == 'mysql') {
168                 
169                 $app->uses('ini_parser');
170                 $package_config = $app->ini_parser->parse_ini_string(stripslashes($software_package['package_config']));
171                 
172                 $this->create_app_db($package_config['mysql']);
173                 $app->log("Creating the app DB.",LOGLEVEL_DEBUG);
174                 
175                 //* Load the sql dump into the database
176                 if(is_file($temp_dir.'/setup.sql')) {
177                     $db_config = $package_config['mysql'];
178                     if(    $db_config['database_user'] != '' &&
179                         $db_config['database_password'] != '' &&
180                         $db_config['database_name'] != '' &&
181                         $db_config['database_host'] != '') {
182                         system("mysql --default-character-set=utf8 --force -h '".$db_config['database_host']."' -u '".$db_config['database_user']."' ".$db_config['database_name']." < ".escapeshellcmd($temp_dir.'/setup.sql'));
183                         $app->log("Loading setup.sql dump into the app db.",LOGLEVEL_DEBUG);
184                     }
185                 }
186                 
187             }
188             
189             //* Save the package config file as app.ini
190             if($software_package['package_config'] != '') {
191                 file_put_contents($temp_dir.'/app.ini',$software_package['package_config']);
192                 $app->log("Writing ".$temp_dir.'/app.ini',LOGLEVEL_DEBUG);
df8a46 193             }
48ced1 194             
T 195             if(is_file($temp_dir.'/setup.sh')) {
196                 // Execute the setup script
197                 exec('chmod +x '.$temp_dir.'/setup.sh');
198                 $app->log("Executing setup.sh file in directory $temp_dir",LOGLEVEL_DEBUG);
df8a46 199                 $cmd = 'cd '.$temp_dir.' && ./setup.sh > package_install.log';
T 200                 if($installuser == '') {
201                     exec($cmd);
202                 } else {
203                     exec("su -c ".escapeshellarg($cmd)." $installuser");
204                 }
086696 205                 
M 206                 $log_data = @file_get_contents("{$temp_dir}/package_install.log");
207                 if(preg_match("'.*\[OK\]\s*$'is", $log_data)) {
208                     $app->log("Installation successful",LOGLEVEL_DEBUG);
209                     $app->log($log_data,LOGLEVEL_DEBUG);
210                     $this->set_install_status($data["new"]["software_update_inst_id"], "installed");
211                 } else {
df8a46 212                     $app->log("Installation failed:\n\n" . $log_data,LOGLEVEL_WARN);
086696 213                     $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
M 214                 }
48ced1 215             } else {
T 216                 $app->log("setup.sh file not found",LOGLEVEL_ERROR);
086696 217                 $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
48ced1 218             }
T 219         } else {
df8a46 220             $app->log("Download of the update file failed",LOGLEVEL_WARN);
086696 221             $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
48ced1 222         }
T 223         
1390c8 224         if($temp_dir != '' && $temp_dir != '/') exec("rm -rf $temp_dir");
48ced1 225         $app->log("Deleting the temp directory $temp_dir",LOGLEVEL_DEBUG);
T 226     }
227     
1390c8 228     private function create_app_db($db_config) {
T 229         global $app, $conf;
230         
231         if(    $db_config['database_user'] != '' &&
232             $db_config['database_password'] != '' &&
233             $db_config['database_name'] != '' &&
234             $db_config['database_host'] != '') {
235             
236             if(!include(ISPC_LIB_PATH.'/mysql_clientdb.conf')) {
237                 $app->log('Unable to open'.ISPC_LIB_PATH.'/mysql_clientdb.conf',LOGLEVEL_ERROR);
238                 return;
239             }
240             
241             if($db_config['database_user'] == 'root') {
242                 $app->log('User root not allowed for App databases',LOGLEVEL_WARNING);
243                 return;
244             }
245         
246             //* Connect to the database
247             $link = mysql_connect($clientdb_host, $clientdb_user, $clientdb_password);
248             if (!$link) {
249                 $app->log('Unable to connect to the database'.mysql_error($link),LOGLEVEL_ERROR);
250                 return;
251             }
252
253             $query_charset_table = '';
254
255             //* Create the new database
256             if (mysql_query('CREATE DATABASE '.mysql_real_escape_string($db_config['database_name']).$query_charset_table,$link)) {
257                 $app->log('Created MySQL database: '.$db_config['database_name'],LOGLEVEL_DEBUG);
258             } else {
259                 $app->log('Unable to connect to the database'.mysql_error($link),LOGLEVEL_ERROR);
260             }
261             
262             if(mysql_query("GRANT ALL ON ".mysql_real_escape_string($db_config['database_name'],$link).".* TO '".mysql_real_escape_string($db_config['database_user'],$link)."'@'".$db_config['database_host']."' IDENTIFIED BY '".mysql_real_escape_string($db_config['database_password'],$link)."';",$link)) {
263             $app->log('Created MySQL user: '.$db_config['database_user'],LOGLEVEL_DEBUG);
264             } else {
265                 $app->log('Unable to create database user'.$db_config['database_user'].' '.mysql_error($link),LOGLEVEL_ERROR);
266             }
267
268             mysql_query("FLUSH PRIVILEGES;",$link);
269             mysql_close($link);
270             
271         }
272         
273     }
48ced1 274
T 275 } // end class
276
8e725d 277 ?>