root/freepbx/trunk/amp_conf/bin/module_admin

Revision 2674, 12.4 kB (checked in by gregmac, 7 years ago)

Finished modules API rework (i think), added new module_admin script

  • Property svn:executable set to *
Line 
1 #!/usr/bin/php
2 <?php
3 /** Command-line Module Administration script
4  * (c) 2006 Greg MacLellan
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  */
16
17 define("AMP_CONF", "/etc/amportal.conf");
18
19 function out($text) {
20     echo $text."\n";
21 }
22
23 function outn($text) {
24     echo $text;
25 }
26
27 function error($text) {
28     echo "[ERROR] ".$text."\n";
29 }
30
31 function fatal($text) {
32     echo "[FATAL] ".$text."\n";
33     exit(1);
34 }
35
36 function debug($text) {
37     global $debug;
38     
39     if ($debug) echo "[DEBUG-preDB] ".$text."\n";
40 }
41
42
43 function install_parse_amportal_conf($filename) {
44     $file = file($filename);
45     foreach ($file as $line) {
46         if (preg_match("/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/",$line,$matches)) {
47             $conf[ $matches[1] ] = $matches[2];
48         }
49     }
50     return $conf;
51 }
52
53 function init_amportal_environment($ampconfpath) {
54     global $amp_conf, $asterisk_conf, $db;
55     
56     if (!file_exists($ampconfpath)) {
57         fatal('Cannot find conf file: '.$ampconfpath);
58     }
59     
60     // primitive parse function, just to grab AMPWEBROOT
61     $inst_amp_conf = install_parse_amportal_conf(AMP_CONF);
62     
63     define('AMP_BASE_INCLUDE_PATH', $inst_amp_conf['AMPWEBROOT'].'/admin');
64     
65     if (!file_exists(AMP_BASE_INCLUDE_PATH.'/functions.inc.php')) {
66         fatal('Cannot locate '.AMP_BASE_INCLUDE_PATH.'/functions.inc.php');
67     }   
68     // include the functions file from WEBROOT
69     include(AMP_BASE_INCLUDE_PATH.'/functions.inc.php');
70     
71     // now apply the real parse function (this makes some default assumptions and does a bit more error checking)
72     $amp_conf = parse_amportal_conf($ampconfpath);
73     
74     $asterisk_conf = parse_asterisk_conf("/etc/asterisk/asterisk.conf");
75
76     // connect to database
77     if (!file_exists(AMP_BASE_INCLUDE_PATH.'/common/db_connect.php')) {
78         fatal('Cannot locate '.AMP_BASE_INCLUDE_PATH.'/common/db_connect.php');
79     }
80     require_once(AMP_BASE_INCLUDE_PATH.'/common/db_connect.php'); //PEAR must be installed
81
82 }
83
84 function showHelp() {
85     global $argv;
86     out("USAGE:");
87     out("  ".$argv[0]." [params] <operation> <module> [parameters.. ] ");
88     out("PARAMETERS: ");
89     out("  -f  Force operation (skips dependency and status checks)");
90     out("      WARNING: Use at your own risk, modules have dependencies for a reason!");
91     out("OPERATIONS:");
92     out("  checkdepends <module>");
93     out("      Check if module meets all dependencies");
94     out("  delete <module>");
95     out("      Disable, uninstall, and delete the specified module");
96     out("  disable <module>");
97     out("      Disable the specified module");
98     out("  download <module>");
99     out("      Download the module from the website");
100     out("      If -f is used, downloads even if there is already a copy.");
101     out("  enable <module>");
102     out("      Enable the specified module");
103     out("  info <module>");
104     out("      Get information about a given module");
105     out("  install <module>");
106     out("      Install the module (must exist in the modules directory)");
107     out("  list");
108     out("      List all local modules and their current status");
109     out("  listonline");
110     out("      List all local and repository modules and their current status");
111     out("  reversedepends <module>");
112     out("      Show all modules that depend on this one");
113     out("  uninstall <module>");
114     out("      Disable and uninstall the specified module");
115     out("  upgrade <module>");
116     out("      Equivalent to running download and install");
117     out("  upgradeall");
118     out("      Downloads and upgrades all modules with pending updates");
119
120     out("  --help, -h, -?           Show this help");
121 }
122
123 function showList($online = false) {
124     $modules_local = module_getinfo();
125     $modules = $modules_local;
126     if ($online) {
127         $modules_online = module_getonlinexml();
128         $modules += $modules_online;
129     }
130     ksort($modules);
131     
132     outn(str_pad("Module", 20));
133     outn(str_pad("Version", 12));
134     out("Status");
135     
136     outn(str_repeat('-', 19).' ');
137     outn(str_repeat('-', 11).' ');
138     out(str_repeat('-', 19).' ');
139     
140     foreach (array_keys($modules) as $name) {
141         
142         switch ($modules[$name]['status']) {
143             case MODULE_STATUS_NOTINSTALLED:
144                 if (isset($modules_local[$name])) {
145                     $status = 'Not Installed (Locally available)';
146                 } else {
147                     $status = 'Not Installed (Available online: '.$modules_online[$name]['version'].')';
148                 }
149             break;
150             case MODULE_STATUS_DISABLED:
151                 $status = 'Disabled';
152             break;
153             case MODULE_STATUS_NEEDUPGRADE:
154                 $status = 'Disabled; Pending upgrade to '.$modules[$name]['version'];
155             break;
156             case MODULE_STATUS_BROKEN:
157                 $status = 'Broken';
158             break;
159             default:
160                 // check for online upgrade
161                 if (isset($modules_online[$name]['version'])) {
162                     $vercomp = version_compare($modules[$name]['version'], $modules_online[$name]['version']);
163                     if ($vercomp < 0) {
164                         $status = 'Online upgrade available ('.$modules_online[$name]['version'].')';
165                     } else if ($vercomp > 0) {
166                         $status = 'Newer than online version ('.$modules_online[$name]['version'].')';
167                     } else {
168                         $status = 'Enabled and up to date';
169                     }
170                 } else if (isset($modules_online)) {
171                     // we're connected to online, but didn't find this module
172                     $status = 'Enabled; Not available online';
173                 } else {
174                     $status = 'Enabled';
175                 }
176             break;
177         }
178         
179         outn(str_pad($name, 20));
180         outn(str_pad($modules[$name]['dbversion'], 12));
181         out($status);
182     }
183 }
184
185 function showCheckDepends($modulename) {
186     $modules = module_getinfo($modulename);
187     if (!isset($modules[$modulename])) {
188         fatal($modulename.' not found');
189     }
190     
191     if (($depmods = module_reversedepends($modulename)) !== false) {
192         out("The following modules depend on this one: ".implode(', ',$depmods));
193         exit(1);
194     } else {
195         out("No enabled modules depend on this module.");
196         exit(0);
197     }
198 }
199 function showReverseDepends($modulename) {
200     $modules = module_getinfo($modulename);
201     if (!isset($modules[$modulename])) {
202         fatal($modulename.' not found');
203     }
204     if (($errors = module_checkdepends($modules[$modulename])) !== true) {
205         out("The following dependencies are not met:");
206         out(' - '.implode("\n - ",$errors));
207         exit(1);
208     } else {
209         out("All dependencies met for this module.");
210         exit(0);
211     }
212 }
213
214 function showInfo($modulename) {
215     function recursive_print($array, $parentkey = '', $level=0) {
216         foreach ($array as $key => $value) {
217             if (is_array($value)) {
218                 // check if there is a numeric key in the sub-array, if so, we don't print the title
219                 if (!isset($value[0])) {
220                     out(str_pad($key,15+($level * 3),' ',STR_PAD_LEFT).': ');
221                 }
222                 recursive_print($value, $key, $level + 1);
223             } else {
224                 if (is_numeric($key)) {
225                     // its just multiple parent keys, so we don't indent, and print the parentkey instead
226                     out(str_pad($parentkey,15+(($level-1) * 3),' ',STR_PAD_LEFT).': '.$value);
227                 } else {
228                     if ($key == 'status') {
229                         switch ($value) {
230                             case MODULE_STATUS_NOTINSTALLED: $value = 'Not Installed'; break;
231                             case MODULE_STATUS_NEEDUPGRADE: $value = 'Disabled; Needs Upgrade'; break;
232                             case MODULE_STATUS_ENABLED: $value = 'Enabled'; break;
233                             case MODULE_STATUS_DISABLED: $value = 'Disabled'; break;
234                             case MODULE_STATUS_BROKEN: $value = 'Broken'; break;
235                         }
236                     }
237                     out(str_pad($key,15+($level * 3),' ',STR_PAD_LEFT).': '.$value);
238                 }
239             }
240         }
241     }
242     $modules = module_getinfo($modulename);
243     if (!isset($modules[$modulename])) {
244         fatal($modulename.' not found');
245     }
246     
247     recursive_print($modules[$modulename]);
248     
249 }
250
251 function doDisable($modulename, $force) {
252     if (is_array($errors = module_disable($modulename, $force))) {
253         out("The following error(s) occured:");
254         out(' - '.implode("\n - ",$errors));
255         exit(2);
256     } else {
257         out("Module successfully disabled");
258         exit(0);
259     }
260 }
261
262 function doEnable($modulename, $force) {
263     if (is_array($errors = module_enable($modulename, $force))) {
264         out("The following error(s) occured:");
265         out(' - '.implode("\n - ",$errors));
266         exit(2);
267     } else {
268         out("Module successfully enabled");
269         exit(0);
270     }
271 }
272
273 function doInstall($modulename, $force) {
274     if (is_array($errors = module_install($modulename, $force))) {
275         out("The following error(s) occured:");
276         out(' - '.implode("\n - ",$errors));
277         exit(2);
278     } else {
279         out("Module successfully installed");
280         exit(0);
281     }
282 }
283
284 function doUninstall($modulename, $force) {
285     if (is_array($errors = module_uninstall($modulename, $force))) {
286         out("The following error(s) occured:");
287         out(' - '.implode("\n - ",$errors));
288         exit(2);
289     } else {
290         out("Module successfully uninstalled");
291         exit(0);
292     }
293 }
294
295 function doDelete($modulename, $force) {
296     if (is_array($errors = module_delete($modulename, $force))) {
297         out("The following error(s) occured:");
298         out(' - '.implode("\n - ",$errors));
299         exit(2);
300     } else {
301         out("Module successfully deleted");
302         exit(0);
303     }
304 }
305
306 function doDownload($modulename, $force) {
307     if (is_array($errors = module_download($modulename, $force, 'download_progress'))) {
308         out("The following error(s) occured:");
309         out(' - '.implode("\n - ",$errors));
310         exit(2);
311     } else {
312         out("Module successfully downloaded");
313         exit(0);
314     }
315 }
316
317 function download_progress($action, $params) {
318     switch ($action) {
319         case 'untar':
320             outn("\nUntaring..");
321         break;
322         case 'downloading':
323             outn("\rDownloading ".$params['read'].' of '.$params['total'].' ('.round($params['read']/$params['total']*100).'%)            ');
324             if ($params['read'] == $params['total']) {
325                 out('');
326             }
327         break;
328         case 'done';
329             out('Done');
330         break;
331     }
332 }
333
334 /****************************************************************************************************
335  ****************************************************************************************************/
336
337 // from  ben-php dot net at efros dot com   at  php.net/install.unix.commandline
338 if (version_compare(phpversion(),'4.3.0','<') || !defined("STDIN")) {
339     define('STDIN',fopen("php://stdin","r"));
340     define('STDOUT',fopen("php://stdout","r"));
341     define('STDERR',fopen("php://stderr","r"));
342     register_shutdown_function( create_function( '' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;' ) );
343 }
344   
345 // **** Make sure we have PEAR's DB.php, and include it
346 if (! @ include('DB.php')) {
347     fatal("PEAR must be installed (requires DB.php). Include path: ".ini_get("include_path"));
348 }
349
350 // **** Make sure we have PEAR's GetOpts.php, and include it
351 if (! @ include("Console/Getopt.php")) {
352     fatal("PEAR must be installed (requires Console/Getopt.php). Include path: ".ini_get("include_path"));
353 }
354
355 // **** Parse out command-line options
356 $shortopts = "h?fc:";
357 $longopts = array("help","debug","config=");
358
359 $args = Console_Getopt::getopt(Console_Getopt::readPHPArgv(), $shortopts, $longopts);
360 if (is_object($args)) {
361     // assume it's PEAR_ERROR
362     out($args->message);
363     exit(255);
364 }
365
366 $ampconfpath = AMP_CONF;
367
368 $force = false;
369
370 foreach ($args[0] as $arg) {
371     switch ($arg[0]) {
372         case "--help": case "h": case "?":
373             showHelp();
374             exit(10);
375         break;
376         case 'f':
377             $force = true;
378         break;
379         case "--config": case "c":
380             $ampconfpath = $arg[1];
381         break;
382     }
383 }
384
385 // create $amp_conf, $db, etc
386 init_amportal_environment($ampconfpath);
387
388 $operation = $args[1][0];
389 $param = $args[1][1];
390
391 if (!isset($argv[1])) {
392     showhelp();
393     exit(10);
394 }
395
396 if ($force) {
397     out('WARNING: "force" is enabled, it is possible to create problems');
398 }
399
400 switch ($operation ) {
401     case 'list':
402         showList();
403     break;
404     case 'listonline':
405         showList(true);
406     break;
407     case 'checkdepends':
408         if (empty($param)) {
409             fatal("Missing module name");
410         }
411         showDepends($param);
412     break;
413     case 'reversedepends':
414         if (empty($param)) {
415             fatal("Missing module name");
416         }
417         showCheckDepends($param);
418     break;
419     case 'info':
420         if (empty($param)) {
421             fatal("Missing module name");
422         }
423         showInfo($param);
424     break;
425     case 'download':
426         if (empty($param)) {
427             fatal("Missing module name");
428         }
429         doDownload($param, $force);
430     break;
431     case 'install':
432     case 'upgrade':
433         if (empty($param)) {
434             fatal("Missing module name");
435         }
436         doInstall($param, $force);
437     break;
438     case 'enable':
439         if (empty($param)) {
440             fatal("Missing module name");
441         }
442         doEnable($param, $force);
443     break;
444     case 'disable':
445         if (empty($param)) {
446             fatal("Missing module name");
447         }
448         doDisable($param, $force);
449     break;
450     case 'uninstall':
451         if (empty($param)) {
452             fatal("Missing module name");
453         }
454         doUninstall($param, $force);
455     break;
456     case 'delete':
457         if (empty($param)) {
458             fatal("Missing module name");
459         }
460         doDelete($param, $force);
461     break;
462     default:
463     case 'help':
464         showhelp();
465         exit(10);
466     break;
467 }
468
469 ?>
Note: See TracBrowser for help on using the browser.