root/freepbx/tags/2.9.0beta1/install_amp

Revision 11147, 39.0 kB (checked in by p_lindheimer, 2 years ago)

closes #4770 adds --force-overwrite which sets check_md5s to false, also some minor cleanup elsewhere. Untested but it should work, report if there are still interactive questions.

  • Property svn:mime-type set to text/plain
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/php -q
2 <?php
3 //This file is part of FreePBX.
4 //
5 //    FreePBX is free software: you can redistribute it and/or modify
6 //    it under the terms of the GNU General Public License as published by
7 //    the Free Software Foundation, either version 2 of the License, or
8 //    (at your option) any later version.
9 //
10 //    FreePBX is distributed in the hope that it will be useful,
11 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //    GNU General Public License for more details.
14 //
15 //    You should have received a copy of the GNU General Public License
16 //    along with FreePBX.  If not, see <http://www.gnu.org/licenses/>.
17 //
18 //    Copyright 2006, qldrob
19 //    Copyright 2009, Bandwith.com
20 //
21 require_once ("libfreepbx.install.php");
22 require_once(dirname(__FILE__) . '/amp_conf/htdocs/admin/libraries/php-upgrade.functions.php');
23 require_once(dirname(__FILE__) . '/amp_conf/htdocs/admin/libraries/sql.functions.php');
24 require_once(dirname(__FILE__) . '/amp_conf/htdocs/admin/libraries/utility.functions.php');
25
26 # constants
27 define("AMP_CONF", "/etc/amportal.conf");
28 define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf");
29 define("UPGRADE_DIR", dirname(__FILE__)."/upgrades");
30 define("MODULE_DIR", dirname(__FILE__)."/amp_conf/htdocs/admin/modules/");
31
32 # semi constants
33 $webroot  = "/var/www/html";
34 $fopwebroot = "";       // if blank, will use $webroot/panel
35 $ampsbin_dir = "/usr/local/sbin"; // default if not set
36 $ampbin_dir = "/var/lib/asterisk/bin";
37 $asterisk_user  = "asteriskuser";
38 $asterisk_pass  = "amp109";
39
40 /********************************************************************************************************************/
41
42 function showHelp() {
43   out("Optional parameters:",false);
44   out("  --help, -h, -?           Show this help",false);
45   out("  --dbhost <ip address>    Use a remote database server",false);
46   out("  --dbname databasename    Use database name specified, instead of 'asterisk'",false);
47   out("  --username <user>        Use <user> to connect to db and write config",false);
48   out("  --password <pass>        Use <pass> to connect to db and write config",false);
49   out("  --fopwebroot <path>      Web path where fop will be installed",false);
50   out("  --webroot <path>         Web root where FreePBX will be installed",false);
51   out("  --cgibin <path>          Path where cgi-bin's lives",false);
52   out("  --bin <path>             Path of asterisk binaries",false);
53   out("  --sbin <path>            Path of system admin binaries",false);
54   out("  --asteriskuser <user>    Asterisk Manager username",false);
55   out("  --asteriskpass <pass>    Asterisk Manager password",false);
56   out("  --systemconfig <path>    System config files",false);
57   out("  --debug                  Enable debug output",false);
58   out("  --dry-run                Don't actually do anything",false);
59   out("  --force-version <ver>    Force upgrade from version <ver>",false);
60   out("  --skip-module-install    Don't run install scripts for packaged modules, the files are still loaded.",false);
61   out("                           In a development environment you may not want the install scripts run.",false);
62   out("  --no-files               Just run updates without installing files",false);
63   out("  --force-overwrite        Don't ask if it is ok to overwrite modified files, assume yes for all.",false);
64   out("  --install-moh            Install default music-on-hold files (normally doesn't, unless ",false);
65   out("                           it's a new installation)",false);
66   out("  --install-fop=false      Don't install FOP and don't display it anywhere on the interface",false);
67   out("  --dev-links              Make links to files in the source directory instead of copying",false);
68   out("                           (intended for developers only)",false);
69   out("  --my-svn-is-correct      Ignore Asterisk version, assume it is correct",false);
70   out("  --engine <name>          Use the specified PBX Engine ('asterisk')",false);
71 }
72
73 function install_parse_amportal_conf($filename) {
74   $file = file($filename);
75   foreach ($file as $line) {
76     if (preg_match("/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/",$line,$matches)) {
77       $conf[ $matches[1] ] = $matches[2];
78     }
79   }
80
81   // use same defaults as function.inc.php
82   if ( !isset($conf["AMPDBENGINE"]) || ($conf["AMPDBENGINE"] == "")) {
83     $conf["AMPDBENGINE"] = "mysql";
84   }
85  
86   if ( !isset($conf["AMPDBNAME"]) || ($conf["AMPDBNAME"] == "")) {
87     $conf["AMPDBNAME"] = "asterisk";
88   }
89  
90   if ( !isset($conf["AMPENGINE"]) || ($conf["AMPENGINE"] == "")) {
91     $conf["AMPENGINE"] = "asterisk";
92   }
93
94   return $conf;
95 }
96
97 function install_parse_asterisk_conf($filename) {
98   $file = file($filename);
99   foreach ($file as $line) {
100     if (preg_match("/^\s*([a-zA-Z0-9]+)\s* => \s*(.*)\s*([;#].*)?/",$line,$matches)) {
101       $conf[ $matches[1] ] = $matches[2];
102     }
103   }
104   // Now set defaults if not set (although asterisk should fail if not set but at least
105   // it will get the setup somewhat right
106   //
107   if (!isset($asterisk_conf['astetcdir']))    { $asterisk_conf['astetcdir']    = "/etc/asterisk"; }
108   if (!isset($asterisk_conf['astmoddir']))    { $asterisk_conf['astmoddir']    = "/usr/lib/asterisk/modules"; }
109   if (!isset($asterisk_conf['astvarlibdir'])) { $asterisk_conf['astvarlibdir'] = "/var/lib/asterisk"; }
110   if (!isset($asterisk_conf['astagidir']))    { $asterisk_conf['astagidir']    = "/var/lib/asterisk/agi-bin"; }
111   if (!isset($asterisk_conf['astspooldir']))  { $asterisk_conf['astspooldir']  = "/var/spool/asterisk"; }
112   if (!isset($asterisk_conf['astrundir']))    { $asterisk_conf['astrundir']    = "/var/run/asterisk"; }
113   if (!isset($asterisk_conf['astlogdir']))    { $asterisk_conf['astlogdir']    = "/var/log/asterisk"; }
114
115   return $conf;
116 }
117
118 function write_amportal_conf($filename, $conf) {
119   $file = file($filename);
120   // parse through the file
121   foreach (array_keys($file) as $key) {
122     if (preg_match("/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/",$file[$key],$matches)) {
123       // this is an option=value line
124       if (isset($conf[ $matches[1] ])) {
125         // rewrite the line, if we have this in $conf
126         $file[$key] = $matches[1]."=".$conf[ $matches[1] ]."\n";
127         // unset it so we know what's new
128         unset($conf[ $matches[1] ]);
129       }
130     }
131   }
132  
133   // add new entries
134   foreach ($conf as $key=>$val) {
135     $file[] = $key."=".$val."\n";
136   }
137  
138   // write the file
139   if (!$fd = fopen($filename, "w")) {
140     fatal("Could not open ".$filename." for writing");
141   }
142   fwrite($fd, implode("",$file));
143   fclose($fd);
144 }
145
146 function ask_overwrite($file1, $file2) {
147   global $check_md5s;
148   do {
149     out($file2." has been changed from the original version.");
150     outn("Overwrite (y=yes/a=all/n=no/d=diff/s=shell/x=exit)? ");
151     $key = fgets(STDIN,1024);
152     switch (strtolower($key[0])) {
153       case "y": return true;
154       case "a": $check_md5s=false; return true;
155       case "n": return false;
156       case "d":
157         out("");
158         // w = ignore whitespace, u = unified
159         passthru("diff -wu ".escapeshellarg($file2)." ".escapeshellarg($file1));
160       break;
161       case "s":
162         if (function_exists("pcntl_fork")) {
163           out("");
164           $shell = (isset($_ENV["SHELL"]) ? $_ENV["SHELL"] : "/bin/bash");
165           out("Dropping to shell. Type 'exit' to return");
166           out("-> Original file:  ".$file2);
167           out("-> New file:       ".$file1);
168          
169           $pid = pcntl_fork();
170           if ($pid == -1) {
171             out("[ERROR] cannot fork");
172           } else if ($pid) {
173             // parent
174             pcntl_waitpid($pid, $status);
175             // we wait till the child exits/dies/whatever
176           } else {
177             pcntl_exec($shell, array(), $_ENV);
178           }
179          
180           out("Returned from shell");
181         } else {
182           out("[ERROR] PHP not built with process control (--enable-pcntl) support: cannot spawn shell");
183         }
184        
185       break;
186       case "x":
187         out("-> Original file:  ".$file2);
188         out("-> New file:       ".$file1);
189         out("Exiting install program.");
190         exit(1);
191       break;
192     }
193     out("");
194   } while(1);
195 }
196
197 /** Write AMP-generated configuration files
198  */
199 function generate_configs() {
200   global $amp_conf;
201   global $dryrun;
202   global $debug;
203  
204   out("Generating Configurations.conf, (if Asterisk is not running, you will get an error");
205   out("In case of error, start Asterisk and hit the red bar in the GUI to generate the Configurations.conf files");
206   if (!$dryrun)
207     // added --run-install to make it work like it has been working since retrieve_conf changed to not run module install scripts by default
208
209     //
210     // TODO: Should check if Asterisk is running and/or try to start it.
211     // TODO: test this
212     //
213     $asteriskuser = isset($amp_conf['AMPASTERISKUSER']) && $amp_conf['AMPASTERISKUSER'] ? $amp_conf['AMPASTERISKUSER'] : 'asterisk';
214     passthru("sudo -u $asteriskuser  ".trim($amp_conf["AMPBIN"])."/retrieve_conf --run-install ".($debug ? ' --debug' : ''));
215 }
216
217
218 /** Collect AMP settings
219  */
220 function collect_settings($filename, $dbhost = '', $dbuser = '', $dbpass = '', $dbname = 'asterisk') {
221   global $webroot;
222   global $fopwebroot;
223   global $ampsbin_dir;
224   global $ampbin_dir;
225   global $asterisk_user;
226   global $asterisk_pass;
227
228   out("Creating new $filename");
229  
230   outn("Enter your USERNAME to connect to the '$dbname' database:\n [".($dbuser ? $dbuser : $asterisk_user) . "] ");
231   $key = trim(fgets(STDIN,1024));
232   if (preg_match('/^$/',$key))
233     $amp_conf["AMPDBUSER"] = ($dbuser ? $dbuser : $asterisk_user);
234   else
235     $amp_conf["AMPDBUSER"] = $key;
236  
237   outn("Enter your PASSWORD to connect to the '$dbname' database:\n [".($dbpass ? $dbpass : $asterisk_pass)."] ");
238   $key = trim(fgets(STDIN,1024));
239   if (preg_match('/^$/',$key))
240     $amp_conf["AMPDBPASS"] = ($dbpass ? $dbpass : $asterisk_pass);
241   else
242     $amp_conf["AMPDBPASS"] = $key;
243  
244   outn("Enter the hostname of the '$dbname' database:\n [".($dbhost ? $dbhost : "localhost")."] ");
245   $key = trim(fgets(STDIN,1024));
246   if (preg_match('/^$/',$key))
247     $amp_conf["AMPDBHOST"] = ($dbhost ? $dbhost : "localhost");
248   else
249     $amp_conf["AMPDBHOST"] = $key;
250  
251   outn("Enter a USERNAME to connect to the Asterisk Manager interface:\n [admin] ");
252   $key = trim(fgets(STDIN,1024));
253   if (preg_match('/^$/',$key)) $amp_conf["AMPMGRUSER"] = "admin";
254   else $amp_conf["AMPMGRUSER"] = $key;
255  
256   outn("Enter a PASSWORD to connect to the Asterisk Manager interface:\n [amp111] ");
257   $key = trim(fgets(STDIN,1024));
258   if (preg_match('/^$/',$key)) $amp_conf["AMPMGRPASS"] = "amp111";
259   else $amp_conf["AMPMGRPASS"] = $key;
260  
261   do {
262     out("Enter the path to use for your AMP web root:\n [$webroot] ");
263     $key = trim(fgets(STDIN,1024));
264     if (preg_match('/^$/',$key))
265       $amp_conf["AMPWEBROOT"] = "$webroot";
266     else
267       $amp_conf["AMPWEBROOT"] = rtrim($key,'/');
268
269     if (is_dir($amp_conf["AMPWEBROOT"])) {
270       break;
271     } else if (amp_mkdir($amp_conf["AMPWEBROOT"],"0755",true)){
272       out("Created ".$amp_conf["AMPWEBROOT"]);
273       break;
274     } else {
275       fatal("Cannot create ".$amp_conf["AMPWEBROOT"]."!");
276     }
277   } while(1);
278  
279   // Really no need to ask, is there.
280   if (empty($fopwebroot))
281     $amp_conf["FOPWEBROOT"] = $amp_conf["AMPWEBROOT"]."/panel";
282   else
283     $amp_conf["FOPWEBROOT"] = $fopwebroot;
284  
285   outn("Enter the IP ADDRESS or hostname used to access the AMP web-admin:\n [xx.xx.xx.xx] ");
286   $key = trim(fgets(STDIN,1024));
287   if (preg_match('/^$/',$key)) $amp_conf["AMPWEBADDRESS"] = "xx.xx.xx.xx";
288   else $amp_conf["AMPWEBADDRESS"] = $key;
289  
290   outn("Enter a PASSWORD to perform call transfers with the Flash Operator Panel:\n [passw0rd] ");
291   $key = trim(fgets(STDIN,1024));
292   if (preg_match('/^$/',$key)) $amp_conf["FOPPASSWORD"] = "passw0rd";
293   else $amp_conf["FOPPASSWORD"] = $key;
294  
295   outn("Use simple Extensions [extensions] admin or separate Devices and Users [deviceanduser]?\n [extensions] ");
296   $key = trim(fgets(STDIN,1024));
297   if (preg_match('/^$/',$key)) $amp_conf["AMPEXTENSIONS"] = "extensions";
298   else $amp_conf["AMPEXTENSIONS"] = $key;
299  
300   do {
301     out("Enter directory in which to store AMP executable scripts:\n [$ampbin_dir] ");
302     $key = trim(fgets(STDIN,1024));
303     if (preg_match('/^$/',$key))
304       $amp_conf["AMPBIN"] = $ampbin_dir;
305     else
306       $amp_conf["AMPBIN"] = rtrim($key,'/');
307
308     if (is_dir($amp_conf["AMPBIN"])) {
309       break;
310     } else if (amp_mkdir($amp_conf["AMPBIN"],"0755",true)){
311       out("Created ".$amp_conf["AMPBIN"]);
312       break;
313     } else {
314       fatal("Cannot create ".$amp_conf["AMPBIN"]."!");
315     }
316   } while(1);
317  
318   do {
319     out("Enter directory in which to store super-user scripts:\n [$ampsbin_dir] ");
320     $key = trim(fgets(STDIN,1024));
321     if (preg_match('/^$/',$key))
322       $amp_conf["AMPSBIN"] = "$ampsbin_dir";
323     else
324       $amp_conf["AMPSBIN"] = rtrim($key,'/');
325
326     if (is_dir($amp_conf["AMPSBIN"])) {
327       break;
328     } else if (amp_mkdir($amp_conf["AMPSBIN"],"0755",true)){
329       out("Created ".$amp_conf["AMPSBIN"]);
330       break;
331     } else {
332       fatal("Cannot create ".$amp_conf["AMPSBIN"]."!");
333     }
334   } while(1);
335  
336   // write amportal.conf
337   write_amportal_conf($filename, $amp_conf);
338   outn(AMP_CONF." written");
339 }
340
341 /** Set base of packaged modules to the versions packaged in the tarball since they are
342  *  getting overwritten with the tarball from anything that may have been updated online.
343  *
344  */
345 function set_base_version() {
346   global $dryrun;
347
348   // read modules list from MODULE_DIR
349   //
350   $included_modules = array();
351   $dir = opendir(MODULE_DIR);
352   while ($file = readdir($dir)) {
353     if ($file[0] != "." && $file[0] != "_" && is_dir(MODULE_DIR."/".$file)) {
354       $included_modules[] = $file;
355     }
356   }
357   closedir($dir);
358
359   foreach ($included_modules as $up_module) {
360     outn("Checking $up_module.. ");
361     if (!$dryrun) {
362       out(set_module_version($up_module));
363     } else {
364       out("Dry Run Not Updated");
365     }
366   }
367 }
368
369 /** Install all modules packaged with the install. We use the force flag because the
370  *  the assumption is that the dependencies are met and the package is able to have
371  *  the modules installed.
372  */
373 function install_modules() {
374   global $dryrun;
375   global $amp_conf;
376
377   // read modules list from MODULE_DIR
378   //
379   $included_modules = array();
380   $dir = opendir(MODULE_DIR);
381   while ($file = readdir($dir)) {
382     if ($file[0] != "." && $file[0] != "_" && is_dir(MODULE_DIR."/".$file)) {
383       $included_modules[] = $file;
384     }
385   }
386   closedir($dir);
387
388   foreach ($included_modules as $up_module) {
389     outn("Checking $up_module.. ");
390     if (!$dryrun) {
391       // special case framework, it should not be installed just enabled.
392       //
393       if ($up_module != 'framework') {
394         system($amp_conf['AMPBIN']."/module_admin --no-warnings -f install $up_module");
395         system($amp_conf['AMPBIN']."/module_admin --no-warnings -f enable $up_module");
396         out("installed");
397       } else {
398         system($amp_conf['AMPBIN']."/module_admin --no-warnings -f enable $up_module");
399         out("enabled");
400       }
401     } else {
402       out("Dry Run Not Installed");
403     }
404   }
405 }
406
407 /** Set the module version number to the packaged version and enable
408  *  module must require not install.php or install.sql script
409  *  this is primarily to package core and framework with FreePBX tarballs
410  *
411  */
412 function set_module_version($module) {
413   global $db;
414
415   $module_dir = MODULE_DIR;
416   $file_path = $module_dir.$module."/module.xml";
417   if (file_exists($file_path)) {
418     // TODO: this is bad, there are other version tags (depends on) but this
419     //       is equivalnet to what publish.pl does, so it expects this to be
420     //       at the top.
421     //
422     $module_xml = file_get_contents($file_path);
423     if (preg_match('/<version>(.+)<\/version>/', $module_xml, $matches)) {
424       $version = $matches[1];
425     } else {
426       fatal("ERROR: $file_path found but no version information");
427     }
428   } else {
429     return  "not packaged, no updating needed";
430   }
431
432   // If we didn't return above, then we found the package as part of the install
433   // tarball and want to update the version info since this might be overwriting
434   // an existing install that has a newer version.
435   //
436   $sql = "SELECT version FROM modules WHERE modulename = '$module'";
437   $result = $db->getCol($sql);
438   if(DB::IsError($result)) {     
439     fatal("error accessing version table: ".$result->getMessage());
440   }
441   $sql = "";
442   if (count($result) == 0) {
443     // insert but disable as we have to first run install scripts which come later
444     $sql = "INSERT INTO modules (modulename, version, enabled) VALUES ('$module', '$version', 0)";
445   } else if ($result[0] != $version) {
446     if (version_compare_freepbx($version, $result[0], "gt")) {
447       // if new version is greater than old, then we disable the module and it will get enabled next when installed
448       //
449       $sql = "UPDATE modules SET version = '$version', enabled = 0 WHERE modulename = '$module'";
450     } else {
451       // if new version is equal to or less than old, then we leave it in the enable/disable state it was in but just
452       // reset the version number.
453       //
454       $sql = "UPDATE modules SET version = '$version' WHERE modulename = '$module'";
455     }
456   }
457   if ($sql) {
458     debug($sql);
459     $result = $db->query($sql);
460     if(DB::IsError($result)) {     
461       fatal("error writing to version table: ".$result->getMessage());
462     }
463     return "updated to $version";
464   } else {
465     return "already at $version";
466   }
467 }
468
469 /********************************************************************************************************************/
470
471 //
472 // TODO: will this work, basically using bootstrap once installed if using to upgrade, etc?
473 /*
474 $bootstrap_settings['skip_astman']) = true;
475 $bootstrap_settings['freepbx_auth'] = false;
476 $restrict_mods = true;
477 if (@include_once(getenv('FREEPBX_CONF') ? getenv('FREEPBX_CONF') : '/etc/freepbx.conf')) {
478   out(_("FreePBX already installed, bootstrapping"));
479 } else if (@include_once('/etc/asterisk/freepbx.conf')) {
480   out(_("FreePBX already installed, bootstrapping"));
481 } else {
482   // all the initialization here instead
483 }
484 */
485
486 // **** Make sure we have STDIN etc
487
488 // from  ben-php dot net at efros dot com   at  php.net/install.unix.commandline
489 if (version_compare(phpversion(),'4.3.0','<') || !defined("STDIN")) {
490   define('STDIN',fopen("php://stdin","r"));
491   define('STDOUT',fopen("php://stdout","r"));
492   define('STDERR',fopen("php://stderr","r"));
493   register_shutdown_function( create_function( '' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;' ) );
494 }
495    
496 // **** Make sure we have PEAR's DB.php, and include it
497
498 outn("Checking for PEAR DB..");
499 if (! @ include('DB.php')) {
500   out("FAILED");
501   fatal("PEAR must be installed (requires DB.php). Include path: ".ini_get("include_path"));
502 }
503 out("OK");
504
505 // **** Make sure we have PEAR's GetOpts.php, and include it
506
507 outn("Checking for PEAR Console::Getopt..");
508 if (! @ include("Console/Getopt.php")) {
509   out("FAILED");
510   fatal("PEAR must be installed (requires Console/Getopt.php). Include path: ".ini_get("include_path"));
511 }
512 out("OK");
513
514 // **** Parse out command-line options
515 $shortopts = "h?u:p:";
516 $longopts = array("help","debug","dry-run","username=","password=","force-version=","dbhost=","no-files","force-overwrite","dbname=","my-svn-is-correct","engine=","webroot=","install-moh","install-fop","make-links-devel","dev-links","skip-module-install");
517
518 $args = Console_Getopt::getopt(Console_Getopt::readPHPArgv(), $shortopts, $longopts);
519 if (is_object($args)) {
520   // assume it's PEAR_ERROR
521   out($args->message);
522   exit(255);
523 }
524
525 $debug = false;
526 $dryrun = false;
527 $install_files = true;
528 $override_astvers = false;
529
530 $install_moh = false;
531 $install_fop = true;
532 $make_links = false;
533 $module_install = true;
534
535 //initialize variables to avoid php notices
536 $dbhost = null;
537 $dbname = null;
538 $new_username = null;
539 $new_password = null;
540
541 foreach ($args[0] as $arg) {
542   switch ($arg[0]) {
543     case "--help": case "h": case "?":
544       showHelp();
545       exit(10);
546     break;
547     case "--dry-run":
548       out("Dry-run only, nothing will be changed");
549       $dryrun = true;
550     break;
551     case "--debug":
552       $debug = true;
553       debug("Debug mode enabled");
554     break;
555     case "--username": case "u":
556       out("Using username: ".$arg[1]);
557       $new_username = $arg[1];
558     break;
559     case "--password": case "p":
560       out("Using password: ".str_repeat("*",strlen($arg[1])));
561       $new_password = $arg[1];
562     break;
563     case "--force-version":
564       $version = $arg[1];
565       out("Forcing upgrade from version ".$version);
566     break;
567     case "--dbhost":
568       $dbhost = $arg[1];
569       out("Using remote database server at ".$dbhost);
570     break;
571     case "--dbname":
572       $dbname = $arg[1];
573       out("Using database ".$dbname);
574     break;
575     case "--no-files":
576       $install_files = false;
577       out("Running upgrade only, without installing files.");
578     break;
579     case "--force-overwrite":
580       $check_md5s = false;
581       out("Overwriting all files including modified ones.");
582     break;
583     case "--my-svn-is-correct":
584       $override_astvers = true;
585     break;
586     case "--engine":
587       if ($arg[1] != 'asterisk') {
588         fatal('Currently only "asterisk" is supported as a PBX engine');
589       }
590       $pbx_engine = $arg[1];
591     break;
592     case "--install-moh":
593       $install_moh = true;
594     break;
595     case "--install-fop":
596       if($arg[1] != "false")  {
597         $install_fop = true;
598         out("FOP will be installed and activated.");
599       }
600       else  {
601         out("FOP will be deactivated in the interface.  Set FOPDISABLE=false in amportal.conf to change later.");
602
603       }
604
605     break;
606     case "--make-links-devel":
607     case "--dev-links":
608       $make_links = true;
609     break;
610     case "--skip-module-install":
611       $module_install = false;
612     break;
613     case "--fopwebroot":
614       $fopwebroot = $arg[1];
615       out("Using fop at ".$fopwebroot);
616     break;
617     case "--webroot":
618       $webroot = $arg[1];
619       out("Using Webroot at ".$webroot);
620     break;
621     case "--cgibin":
622       $cgibin = $arg[1];
623       out("Using CGI-BIN at ".$cgibin);
624     break;
625     case "--bin":
626       $ampbin_dir = $arg[1];
627       out("Using bin at ".$ampbin_dir);
628     break;
629     case "--sbin":
630       $ampsbin_dir = $arg[1];
631       out("Using sbin ar ".$ampsbin_dir);
632     break;
633     case "--asteriskuser":
634       $asterisk_user = $arg[1];
635       out("Using Asterisk user ".$asterisk_user);
636     break;
637     case "--asteriskpass":
638       $asterisk_pass = $arg[1];
639       out("Using asteriskpass ".str_repeat("*",strlen($arg[1])));
640     break;
641
642 /*    do we need this ?
643     case "--systemconfig":
644       $systemconfig = $arg[1];
645       out("Using system config at ". $systemconfig);
646     break;
647 */
648
649   }
650 }
651
652
653 // **** Look for user = root
654
655 // TODO: if we bootstrap, do this first before even trying. Also, is their a problem boostraping as user root???
656 //
657 outn("Checking user..");
658 //$current_user=(isset($_ENV["USER"]) ? $_ENV["USER"] : exec('whoami',$output));
659 $euid = (posix_getpwuid(posix_geteuid()));
660 $current_user = $euid['name'];
661 if ($current_user != "root"){
662   out("FAILED");
663   fatal($argv[0]." must be run as root");
664 }
665 out("OK");
666
667
668 // TODO: if we bootstrap, do this first before even trying.
669 //
670 outn("Checking if Asterisk is running..");
671 exec("pidof asterisk", $pid_val, $ret);
672 if ($ret) {
673   out("FAILED");
674   fatal($argv[0]."\n\tAsterisk must be running. If this is a first time install, you should start\n\tAsterisk by typing './start_asterisk start'\n\tFor upgrading, you should run 'amportal start'");
675 }
676 out("running with PID: ".$pid_val[0]."..OK");
677
678 // **** Check for amportal.conf, create if necessary
679
680 outn("Checking for ".AMP_CONF."..");
681 if (!file_exists(AMP_CONF)) {
682   out(AMP_CONF." does not exist, copying default");
683   copy("amportal.conf", AMP_CONF);
684
685   // this file contains password and should not be a+r
686   // this addresses http://freepbx.org/trac/ticket/1878
687   chown(AMP_CONF, "asterisk");
688   chgrp(AMP_CONF, "asterisk");
689   chmod(AMP_CONF, 0640);
690
691   collect_settings(AMP_CONF, $dbhost, $new_username, $new_password, 'asterisk');
692
693   out("Assuming new install, --install-moh added to command line");
694   $install_moh = true;
695 }
696 out("OK");
697
698 // **** read amportal.conf
699
700 // TODO: see comments above, have we already boostraped, if so, skip this?
701 //
702 outn("Reading ".AMP_CONF."..");
703 $amp_conf = install_parse_amportal_conf(AMP_CONF);
704 if (count($amp_conf) == 0) {
705   fatal("FAILED");
706 }
707 out("OK");
708
709 // TODO: if we boostrapped I think we can count on ALL of these being set but maybe it's
710 //       fine to do a sanity check?
711 //
712 // Ensure our "critical" variables are set.  We absolutely need these to copy in files.
713
714 if (!array_key_exists("AMPWEBROOT",$amp_conf)) {
715   out("Adding AMPWEBROOT option to amportal.conf - using AMP default");
716   $amp_conf["AMPWEBROOT"] = "/var/www/html";
717 }
718 if (!array_key_exists("FOPWEBROOT",$amp_conf)) {
719   out("Adding FOPWEBROOT option to amportal.conf - using AMP default");
720   $amp_conf["FOPWEBROOT"] = $amp_conf["AMPWEBROOT"]."/panel";
721 }
722 if (!array_key_exists("AMPBIN",$amp_conf)) {
723   out("Adding AMPBIN option to amportal.conf - using AMP default");
724   $amp_conf["AMPBIN"] = "/var/lib/asterisk/bin";
725 }
726 if (!array_key_exists("AMPSBIN",$amp_conf)) {
727   out("Adding AMPSBIN option to amportal.conf - using AMP default");
728   $amp_conf["AMPSBIN"] = "/usr/sbin";
729 }
730 if (!array_key_exists("AMPDBENGINE",$amp_conf)) {
731   out("Adding AMPDBENGINE option to amportal.conf - using AMP default");
732   $amp_conf["AMPDBENGINE"] = "mysql";
733 }
734 if (!array_key_exists("AMPDBNAME",$amp_conf)) {
735   out("Adding AMPDBNAME option to amportal.conf - using AMP default");
736   $amp_conf["AMPDBNAME"] = "asterisk";
737 }
738
739 // TODO: if we boostrapped do we ignore these? (Can they even be set?)
740 //
741 if (isset($new_username)) {
742   $amp_conf["AMPDBUSER"] = $new_username;
743 }
744 if (isset($new_password)) {
745   $amp_conf["AMPDBPASS"] = $new_password;
746 }
747 if (isset($dbhost)) {
748   $amp_conf["AMPDBHOST"] = $dbhost;
749 }
750 if (isset($dbname)) {
751   $amp_conf["AMPDBNAME"] = $dbname;
752 }
753 if(!$install_fop)  { // Set from --install-fop parameter; Add it to amportal.conf
754   out("Adding FOPDISABLE option to amportal.conf");
755   $amp_conf["FOPDISABLE"] = "true";
756 }
757 // If they pre-set this in their amportal.conf or this is an upgrade, we should honor it as well
758 //
759 // TODO: if we boostrap, then this value could be normalized (1/0 I think?)
760 //
761 if (isset($amp_conf['FOPDISABLE']) && (strtolower(trim($amp_conf['FOPDISABLE'])) == 'true' || strtolower(trim($amp_conf['FOPDISABLE'])) == 'yes' || strtolower(trim($amp_conf['FOPDISABLE'])) == 'y') )  {
762   $install_fop = false;
763 }
764 // write amportal.conf
765 // TODO: if we boostrapped we don't want to write amportal.conf, or do we? e.g. if we are running out of the file vs. the
766 //       database then we probably want to write, though there should be a freepbx_conf class to use that does that and knows
767 //       how to make that decsion as well as what to write?
768 //
769 write_amportal_conf(AMP_CONF, $amp_conf);
770
771 // **** Check for amportal.conf, create if necessary
772
773 outn("Checking for ".ASTERISK_CONF."..");
774 if (!file_exists(ASTERISK_CONF)) {
775   out(ASTERISK_CONF." does not exist, copying default");
776   copy("asterisk.conf", ASTERISK_CONF);
777 }
778 out("OK");
779
780 // **** read asterisk.conf
781
782 // TODO: if we boostrapped don't do this
783 //
784 outn("Reading ".ASTERISK_CONF."..");
785 $asterisk_conf = install_parse_asterisk_conf(ASTERISK_CONF);
786 if (count($asterisk_conf) == 0) {
787   fatal("FAILED. Have you installed Asterisk?");
788 }
789 out("OK");
790
791 /* TODO: if we boostrapped this should have been done but doesn't hurt?
792  */
793 if (isset($asterisk_conf['astetcdir'])) { $amp_conf['ASTETCDIR'] = $asterisk_conf['astetcdir']; }
794 if (isset($asterisk_conf['astmoddir'])) { $amp_conf['ASTMODDIR'] = $asterisk_conf['astmoddir']; }
795 if (isset($asterisk_conf['astvarlibdir'])) { $amp_conf['ASTVARLIBDIR'] = $asterisk_conf['astvarlibdir']; }
796 if (isset($asterisk_conf['astagidir'])) { $amp_conf['ASTAGIDIR'] = $asterisk_conf['astagidir']; }
797 if (isset($asterisk_conf['astspooldir'])) { $amp_conf['ASTSPOOLDIR'] = $asterisk_conf['astspooldir']; }
798 if (isset($asterisk_conf['astrundir'])) { $amp_conf['ASTRUNDIR'] = $asterisk_conf['astrundir']; }
799 if (isset($asterisk_conf['astlogdir'])) { $amp_conf['ASTLOGDIR'] = $asterisk_conf['astlogdir']; }
800
801 if (!isset($pbx_engine)) { $pbx_engine='asterisk'; }
802 out("Using $pbx_engine as PBX Engine");
803 $amp_conf["AMPENGINE"]=$pbx_engine;
804
805 // TODO: I guess we have new variables set, of course see note above if we boostrapped. Probably
806 //       this one stays?
807 //
808 write_amportal_conf(AMP_CONF, $amp_conf);
809
810
811 // **** Write asterisk version to ASTETCDIR/version
812
813 // TODO: does anything use this? What's the point? (other than we need the version for below)
814 //
815 $tmpoutput = '';
816 $tmpout = exec("asterisk -V", $tmpoutput, $exitcode);
817 if ($exitcode != 0) {
818   fatal("Error executing asterisk: be sure Asterisk is installed and in the path");
819 }
820 if (!$fd = fopen($amp_conf['ASTETCDIR'].'/version','w')) {
821   fatal('Cannot open '.$amp_conf['ASTETCDIR'].'/version for writing');
822 }
823 fwrite($fd, $tmpout);
824 fclose($fd);
825 // change to read-only
826 chmod($amp_conf['ASTETCDIR'].'/version',0444);
827
828
829 // normally this would be the contents of ASTETCDIR/version, but this is for simplicity, as we just read it above
830 $verinfo = $tmpout;
831
832 // **** Check asterisk version
833 //  Set the 'engine' to be 'asterisk14' if using asterisk 1.4, otherwise
834 //  'asterisk'
835 outn("Checking for Asterisk version..");
836 if ((preg_match('/^Asterisk (\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) ||
837     (preg_match('/^Asterisk SVN-(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches))) {
838   if ((version_compare($matches[1], "1.2") < 0)) {
839     fatal("Asterisk 1.2, 1.4, 1.6, or 1.8 is required for this version of FreePBX. Detected version is: ".$matches[1]);
840   }
841   if (version_compare($matches[1], "1.9", "ge")) {
842     fatal("Asterisk 1.2, 1.4, 1.6, or 1.8 is required for this version of FreePBX. Detected version is: ".$matches[1]);
843   }
844   out("{$matches[1]}");
845   $asterisk_version = $matches[1];
846
847 } elseif (preg_match('/^Asterisk ([ABC]\.\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) {
848   if (substr($matches[1], 0, 1) == "A") {
849     fatal("Asterisk Business Edition B or C is required for this version of FreePBX. Detected version is: ".$matches[1]);
850   }
851   out("{$matches[1]}");
852   $asterisk_version = '1.4'; //Not really, but this makes sure that proper execution occurs later on reload commands, etc.
853
854 } elseif ($asterisk_version = preg_match('/^Asterisk SVN.+/', $verinfo)) {
855   out("FAIL");
856   out("*** WARNING ***");
857   out("You are not using a released version of Asterisk. We are unable to verify");
858   out("that your Asterisk version is compatible with FreePBX. Whilst this probably");
859   out("won't cause any problems, YOU NEED TO BE CERTAIN that it is compatible");
860   out("with at least the released Asterisk version 1.2" );
861   if ($override_astvers==false) {
862     out("If you are SURE that this is compatible, you can re-run ".$argv[0]." with");
863     out("the parameter --my-svn-is-correct");
864     exit;
865   } else {
866     out("--my-svn-is-correct specified, continuing");
867   }
868 } else {
869   fatal("Could not determine asterisk version (got: \"".$verinfo."\" please report this)");
870 }
871
872 // **** Make sure selinux isn't enabled
873
874 outn("Checking for selinux..");
875 $tmpoutput;
876 $tmpout = exec("getenforce", $tmpoutput, $sereturn);
877 if (strtolower($tmpoutput[0]) === "enabled") {
878         // this method seems better because disabled and permissive are the same
879         // if a user installs and realizes selinux is running the other method
880         // requires a reboot to get selinuxenabled to work after editing the  selinux config
881         // this will allow you to use setenforce 0 which turns selinux into permissive mode which
882         // doesnt enforce, it just warns.
883   fatal("selinux is ENABLED. This is not supported. Please disable selinux before using FreePBX");
884 }
885 out("OK");
886
887 // **** Connect to database
888
889 // TODO: if we bootstrapped, we are already connected and this can all be skipped
890 //
891 outn("Connecting to database..");
892
893 $db_engine = $amp_conf["AMPDBENGINE"];
894 if ($db_engine != "sqlite3") {
895   $db_user = $amp_conf["AMPDBUSER"];
896   $db_pass = $amp_conf["AMPDBPASS"];
897   $db_host = $amp_conf["AMPDBHOST"];
898 }
899 $db_name = $amp_conf["AMPDBNAME"];
900
901 // we still support older configurations,  and fall back
902 // into mysql when no other engine is defined
903 if ($db_engine == "")
904 {
905   $db_engine = "mysql";
906 }
907  
908 switch ($db_engine)
909 {
910   case "pgsql":
911   case "mysql":
912     // datasource in in this style: dbengine://username:password@host/database
913     if (!function_exists($db_engine.'_connect')) {
914       out("FAILED");
915       fatal($db_engine." PHP libraries not installed");
916     }
917  
918     $datasource = $db_engine.'://'.$db_user.':'.$db_pass.'@'.$db_host.'/'.$db_name;
919     $db = DB::connect($datasource); // attempt connection
920     break;
921  
922   case "sqlite":
923     die_freepbx("SQLite2 support is deprecated. Please use sqlite3 only.");
924     break;
925  
926   case "sqlite3":
927     if (!isset($amp_conf["AMPDBFILE"]))
928       die("You must setup properly AMPDBFILE in /etc/amportal.conf");
929      
930     if (isset($amp_conf["AMPDBFILE"]) == "")
931       die("AMPDBFILE in /etc/amportal.conf cannot be blank");
932
933     /* on centos this extension is not loaded by default */
934     if (! extension_loaded('sqlite3.so')  && ! extension_loaded('SQLITE3'))
935       dl('sqlite3.so');
936
937     if (! @require_once('DB/sqlite3.php') )
938     {
939       out("FAILED");
940       fatal( "Your PHP installation has no PEAR/SQLite3 support. Please install php-sqlite3 and php-pear.");
941     }
942
943     $datasource = "sqlite3:///" . $amp_conf["AMPDBFILE"] . "?mode=0666";
944     $db = DB::connect($datasource);
945     break;
946
947   default:
948     die( "Unknown SQL engine: [$db_engine]");
949 }
950
951 if(DB::IsError($db)) {
952   out("FAILED");
953   debug($db->userinfo);
954   out("Try running ".$argv[0]." --username=user --password=pass  (using your own user and pass)");
955   fatal("Cannot connect to database");
956  
957 }
958 out("OK");
959
960
961 // **** Read DB for version info
962
963 if (!isset($version)) {
964   outn("Checking current version of AMP..");
965   $version = install_getversion();
966   if (!$version) {
967     out("no version information");
968     out("Assuming new installation");
969   } else {
970     out($version);
971   }
972 }
973
974 // Check if freepbx_settings is there and has been initialized
975 // if it has anything less than about 5 settings in it (and that
976 // is probably quite low) then something is wrong so assume it
977 // is not there.
978 //
979 $sql = "SELECT count(*) FROM freepbx_settings";
980 $num_settings = $db->getOne($sql);
981 $force_amportal_conf = DB::IsError($num_settings) || $num_settings < 5;
982
983 // **** Copy files
984
985 if ($install_files)
986 {
987   outn("Installing new FreePBX files..");
988   $check_md5s=true;
989   $md5sums = read_md5_file(UPGRADE_DIR."/".$version.".md5");
990   list($num_files, $num_copied) = recursive_copy("amp_conf", "", $md5sums);
991   if (!is_file("/etc/asterisk/voicemail.conf")) copy("/etc/asterisk/voicemail.conf.template","/etc/asterisk/voicemail.conf");
992   if (!is_dir("/var/spool/asterisk/voicemail/device")) amp_mkdir("/var/spool/asterisk/voicemail/device", "0755", true);
993   out("OK (".$num_copied." files copied, ".($num_files-$num_copied)." skipped)");
994
995   // link the packed js library for ARI, if there the error will indicate that
996   $libfreepbx = $amp_conf['AMPWEBROOT'].'/admin/common/libfreepbx.javascripts.js';
997   $dest_libfreepbx = $amp_conf['AMPWEBROOT'].'/recordings/theme/js/libfreepbx.javascripts.js';
998   if (file_exists($libfreepbx) && !file_exists($dest_libfreepbx)) {
999     outn(_("linking libfreepbx.javascripts.js to theme/js.."));
1000     if (link($libfreepbx, $dest_libfreepbx)) {
1001       out(_("ok"));
1002     } else {
1003       out(_("possible error - check warning message"));
1004     }
1005   }
1006 }
1007
1008 // **** Apply amportal.conf configuration to files
1009 if (file_exists(dirname(__FILE__)."/apply_conf.sh")) {
1010   debug("Running ".dirname(__FILE__)."/apply_conf.sh");
1011 }
1012
1013 outn("Configuring install for your environment..");
1014 if (!$dryrun) {
1015   $asteriskuser = isset($amp_conf['AMPASTERISKUSER']) && $amp_conf['AMPASTERISKUSER'] ? $amp_conf['AMPASTERISKUSER'] : 'asterisk';
1016
1017   if (file_exists($amp_conf["AMPSBIN"]."/amportal")) {
1018     exec("chmod u+x ".$amp_conf["AMPSBIN"]."/amportal");
1019     outn("amportal..");
1020   } else {
1021     outn("no amportal..");
1022   }
1023   if (file_exists($amp_conf["AMPSBIN"]."/fpbx")) {
1024     exec("chmod u+x ".$amp_conf["AMPSBIN"]."/fpbx");
1025     outn("fpbx..");
1026   } else {
1027     outn("no fpbx..");
1028   }
1029   if (file_exists($amp_conf["AMPBIN"]."/freepbx_engine")) {
1030     exec("chmod u+x ".$amp_conf["AMPBIN"]."/freepbx_engine");
1031     outn("freepbx_engine..");
1032   } else {
1033     outn("no freepbx_engine..");
1034   }
1035   out("done");
1036   // edit conf file passwords and then
1037   // reload manager in asterisk if it is running:
1038   //
1039   outn("apply username/password changes to conf files..");
1040   if (file_exists(dirname(__FILE__)."/apply_conf.sh")) {
1041     if ($force_amportal_conf) {
1042       putenv('FORCE_AMPORTAL_CONF=1');
1043       exec(dirname(__FILE__)."/apply_conf.sh ".AMP_CONF);
1044       putenv('FORCE_AMPORTAL_CONF=');
1045     } else {
1046       exec(dirname(__FILE__)."/apply_conf.sh");
1047     }
1048   }
1049   out("done");
1050
1051   /* As of Asterisk 1.4.16 or there about, a missing #include file will make the reload fail. So
1052     we need to make sure that we have such for everything that is in our configs. We will simply
1053     look for the #include statements and touch the files vs. trying to inventory everything we may
1054     need and then forgetting something.
1055   */
1056  
1057   outn("creating missing #include files..");
1058   $include_err = false;
1059   exec("grep '#include' ".$amp_conf['ASTETCDIR']."/*.conf | sed 's/;.*//; s/#include//'",$output,$retcode);
1060   if ($retcode != 0) {
1061     out("Error code $retcode: trying to search for missing #include files");
1062     $include_err = true;
1063   }
1064
1065   foreach($output as $file) {
1066     if (trim($file) == '') {
1067       continue;
1068     }
1069     $parse1 = explode(':',$file);
1070     $parse2 = explode(';',$parse1[1]);
1071     $rawfile = trim($parse2[0]);
1072     if ($rawfile == '') {
1073       continue;
1074     }
1075
1076     $target = ($rawfile[0] == '/') ? $rawfile : $amp_conf['ASTETCDIR']."/$rawfile";
1077
1078     if (!file_exists($target)) {
1079       exec("sudo -u $asteriskuser touch $target", $output, $retcode);
1080         if ($retcode != 0) {
1081         out("Error code $retcode: trying to create empty file $target");
1082         $include_err = true;
1083       }
1084     }
1085   }
1086   if (! $include_err) {
1087     out("OK");
1088   }
1089   // reload manager in asterisk if it was running:
1090   //
1091   if (version_compare($asterisk_version,'1.4','ge')) {
1092     system("asterisk -rx 'module reload manager'");
1093   } else {
1094     system("asterisk -rx 'reload manager'"); //1.2 syntax
1095   }
1096 }
1097 out("OK");
1098
1099 // **** Create spool directories for monitor and fax
1100 if (!is_dir($amp_conf["ASTSPOOLDIR"]."/monitor"))
1101   amp_mkdir($amp_conf["ASTSPOOLDIR"]."/monitor","0766",true);
1102 if (!is_dir($amp_conf["ASTSPOOLDIR"]."/fax"))
1103   amp_mkdir($amp_conf["ASTSPOOLDIR"]."/fax","0766",true);
1104
1105
1106 // **** Set permissions all files
1107
1108 // tell amportal/freepbx_engine to use amportal.conf and not bootstrap
1109 // if freepbx_settings has not been setup yet or you will get an error.
1110 //
1111 if ($install_files)
1112 {
1113   outn("Setting permissions on files..");
1114   if (!$dryrun) {
1115     if ($force_amportal_conf) {
1116       putenv('FORCE_AMPORTAL_CONF=1');
1117     }
1118     exec($amp_conf["AMPSBIN"]."/amportal chown");
1119     if ($force_amportal_conf) {
1120       putenv('FORCE_AMPORTAL_CONF=');
1121     }
1122   }
1123   out("OK");
1124 }
1125
1126 // Run through all the upgrade scripts starting at the specified version
1127 //
1128 upgrade_all($version);
1129
1130 outn("Creating or updating freepbx_conf settings..");
1131 freepbx_settings_init(true);
1132 out("..OK");
1133
1134 // **** Generate AMP configs
1135 out("Generating AMP configs..");
1136 generate_configs();
1137 out("Generating AMP configs..OK");
1138
1139 $version = install_getversion();
1140
1141 if($install_fop && $amp_conf["FOPRUN"])  {
1142   // **** Bounce FOP
1143   outn("Restarting Flash Operator Panel..");
1144   exec("sudo -u $asteriskuser ".$amp_conf["AMPBIN"].'/bounce_op.sh');
1145   out("OK");
1146 }
1147
1148 // Now force an install for all modules that are packaged with the tarball
1149 // directory.
1150 //
1151 if ($module_install) {
1152   install_modules();
1153 } else {
1154   out("bypassing packaged module installation because --skip-module-install flag");
1155 }
1156
1157
1158 // **** Set reload flag for AMP admin
1159 needreload();
1160
1161 if ($amp_conf["AMPWEBADDRESS"])
1162 {
1163   out("Please update your modules and reload Asterisk by visiting http://".$amp_conf["AMPWEBADDRESS"]."/admin",false);
1164 }
1165 else
1166 {
1167   out("Please update your modules and reload Asterisk by browsing to your server.",false);
1168 }
1169
1170 out("",false);
1171 out("*************************************************************************",false);
1172 out("* Note: It's possible that if you click the red 'Update Now' bar BEFORE *",false);
1173 out("* updating your modules, your machine will start dropping calls. Ensure *",false);
1174 out("* that all modules are up to date BEFORE YOU CLICK THE RED BAR. As long *",false);
1175 out("* as this is observed, your machine will be fully functional whilst the *",false);
1176 out("* upgrade is in progress.                                               *",false);
1177 out("*************************************************************************",false);
1178 ?>
Note: See TracBrowser for help on using the browser.