PageRenderTime 62ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/engine/imscp-rqst-mngr

https://github.com/gOOvER/imscp
Perl | 640 lines | 502 code | 76 blank | 62 comment | 42 complexity | 2e970820c20dfea131ca715e73d5c58f MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, GPL-2.0
  1. #!/usr/bin/perl
  2. # i-MSCP - internet Multi Server Control Panel
  3. # Copyright (C) 2010-2015 by internet Multi Server Control Panel
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program 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 this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. #
  19. # @category i-MSCP
  20. # @copyright 2010-2015 by i-MSCP | http://i-mscp.net
  21. # @author Daniel Andreca <sci2tech@gmail.com>
  22. # @author Laurent Declercq <l.declercq@nuxwin.com>
  23. # @link http://i-mscp.net i-MSCP Home Site
  24. # @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2
  25. use strict;
  26. use warnings;
  27. no if $] >= 5.017011, warnings => 'experimental::smartmatch';
  28. use FindBin;
  29. use lib "$FindBin::Bin", "$FindBin::Bin/PerlLib", "$FindBin::Bin/PerlVendor";
  30. use iMSCP::Debug;
  31. use iMSCP::Bootstrapper;
  32. use iMSCP::EventManager;
  33. use iMSCP::Execute;
  34. use MIME::Base64;
  35. use iMSCP::Getopt;
  36. use File::Basename;
  37. use JSON;
  38. # Set umask ( default is 0 when this script is run through the i-MSCP daemon, which leads to some problems )
  39. umask 0022;
  40. # Turn off localisation features to force any command output to be in english
  41. $ENV{'LANG'} = 'C';
  42. # Do not clear screen at end of script
  43. $ENV{'IMSCP_CLEAR_SCREEN'} = 0;
  44. newDebug('imscp-rqst-mngr.log');
  45. # Initialize command line options
  46. $main::execmode = '';
  47. # Parse command line options
  48. iMSCP::Getopt->parseNoDefault(sprintf("Usage: perl %s [OPTION]...", basename($0)) . qq {
  49. Script which process i-MSCP backend requests.
  50. OPTIONS:
  51. -s, --setup Setup mode.
  52. -v, --verbose Enable verbose mode.},
  53. 'setup|s' => sub { $main::execmode = 'setup'; },
  54. 'verbose|v' => sub { setVerbose(@_); }
  55. );
  56. iMSCP::Bootstrapper->getInstance()->boot({ 'norequirements' => 'yes' });
  57. my $dbh = iMSCP::Database->factory()->getRawDb();
  58. sub _process
  59. {
  60. my ($moduleName, $sql, $ipModule) = @_;
  61. my $rs = 0;
  62. debug("Processing $moduleName module items");
  63. if ($main::execmode ne 'setup') {
  64. debug("Processing $moduleName items.");
  65. }
  66. my $rows = $dbh->selectall_arrayref($sql, { Slice => { } });
  67. if(!defined $rows || $dbh->err) {
  68. error($dbh->errstr);
  69. return 1;
  70. }
  71. if(@{$rows}) {
  72. my $i = 1;
  73. my $totalItems = scalar @{$rows};
  74. for my $row(@{$rows}) {
  75. my ($id, $name, $status) = ($row->{'id'}, $row->{'name'}, $row->{'status'});
  76. $$ipModule++ if $moduleName ~~ ['Domain', 'Subdomain', 'Alias', 'SubAlias'];
  77. debug("Processing $id, $name, $status");
  78. print STDOUT ("$moduleName\t$status\t$name\t$id\t$totalItems\t$i\n") if $main::execmode eq 'setup';
  79. $i++;
  80. newDebug("${moduleName}_module_$name.log");
  81. my $module = "Modules::$moduleName";
  82. eval "require $module";
  83. unless($@) {
  84. $rs = $module->new()->process($id);
  85. } else {
  86. error($@);
  87. $rs = 1;
  88. }
  89. endDebug();
  90. if($rs) {
  91. error("Error while processing $id, $name, $status.");
  92. error("See $main::imscpConfig{'LOG_DIR'}/${moduleName}_module_$name.log for more details.");
  93. }
  94. return $rs if $rs;
  95. }
  96. } else {
  97. debug("No item to process for the $moduleName module.");
  98. }
  99. 0;
  100. }
  101. sub run
  102. {
  103. # Process plugins
  104. # Must always be processed first to allow plugins to register their listeners on the event manager
  105. my $rs = _process(
  106. 'Plugin',
  107. "
  108. SELECT
  109. plugin_id AS id, plugin_name AS name, plugin_status AS status
  110. FROM
  111. plugin
  112. WHERE
  113. plugin_status IN ('enabled', 'toinstall', 'toenable', 'toupdate', 'tochange', 'todisable', 'touninstall')
  114. AND
  115. plugin_error IS NULL
  116. AND
  117. plugin_backend = 'yes'
  118. ORDER BY
  119. plugin_priority DESC
  120. "
  121. );
  122. $rs ||= iMSCP::EventManager->getInstance()->trigger('beforeDispatchRequest');
  123. # Process toadd|tochange SSL certificates tasks
  124. $rs ||= _process(
  125. 'SSLcertificate',
  126. "
  127. SELECT
  128. cert_id AS id, domain_type AS name, status AS status
  129. FROM
  130. ssl_certs
  131. WHERE
  132. status IN ('toadd', 'tochange', 'todelete')
  133. ORDER BY
  134. cert_id ASC
  135. "
  136. );
  137. # Process toadd|tochange users tasks
  138. $rs ||= _process(
  139. 'User',
  140. "
  141. SELECT
  142. admin_id AS id, admin_name AS name, admin_status AS status
  143. FROM
  144. admin
  145. WHERE
  146. admin_type = 'user'
  147. AND
  148. admin_status IN ('toadd', 'tochange')
  149. ORDER BY
  150. admin_id ASC
  151. "
  152. );
  153. my $ipsModule = 0;
  154. # Process toadd|tochange|torestore|toenable|todisable domain tasks
  155. # (for each entitty, process only if the parent entity is in a consistent state)
  156. $rs ||= _process(
  157. 'Domain',
  158. "
  159. SELECT
  160. domain_id AS id, domain_name AS name, domain_status AS status
  161. FROM
  162. domain
  163. INNER JOIN
  164. admin ON(admin_id = domain_admin_id)
  165. WHERE
  166. domain_status IN ('toadd', 'tochange', 'torestore', 'toenable', 'todisable')
  167. AND
  168. admin_status IN('ok', 'disabled')
  169. ORDER BY
  170. domain_id ASC
  171. ",
  172. \$ipsModule
  173. );
  174. # Process toadd|tochange|torestore|toenable|todisable subdomains tasks
  175. # (for each entitty, process only if the parent entity is in a consistent state)
  176. $rs ||= _process(
  177. 'Subdomain',
  178. "
  179. SELECT
  180. subdomain_id AS id, subdomain_name AS name, subdomain_status AS status
  181. FROM
  182. subdomain
  183. INNER JOIN
  184. domain USING(domain_id)
  185. WHERE
  186. subdomain_status IN ('toadd', 'tochange', 'torestore', 'toenable', 'todisable')
  187. AND
  188. domain_status IN('ok', 'disabled')
  189. ORDER BY
  190. subdomain_id ASC
  191. ",
  192. \$ipsModule
  193. );
  194. # Process toadd|tochange|torestore|toenable|todisable domain aliases tasks
  195. # (for each entitty, process only if the parent entity is in a consistent state)
  196. $rs ||= _process(
  197. 'Alias',
  198. "
  199. SELECT
  200. alias_id AS id, alias_name AS name, alias_status AS status
  201. FROM
  202. domain_aliasses
  203. INNER JOIN
  204. domain USING(domain_id)
  205. WHERE
  206. alias_status IN ('toadd', 'tochange', 'torestore', 'toenable', 'todisable')
  207. AND
  208. domain_status IN('ok', 'disabled')
  209. ORDER BY
  210. alias_id ASC
  211. ",
  212. \$ipsModule
  213. );
  214. # Process toadd|tochange|torestore|toenable|todisable subdomains of domain aliases tasks
  215. # (for each entitty, process only if the parent entity is in a consistent state)
  216. $rs ||= _process(
  217. 'SubAlias',
  218. "
  219. SELECT
  220. subdomain_alias_id AS id, subdomain_alias_name AS name, subdomain_alias_status AS status
  221. FROM
  222. subdomain_alias
  223. INNER JOIN
  224. domain_aliasses USING(alias_id)
  225. WHERE
  226. subdomain_alias_status IN ('toadd', 'tochange', 'torestore', 'toenable', 'todisable')
  227. AND
  228. alias_status IN('ok', 'disabled')
  229. ORDER BY
  230. subdomain_alias_id ASC
  231. ",
  232. \$ipsModule
  233. );
  234. # Process toadd|tochange|toenable|todisable|todelete mail tasks
  235. # (for each entitty, process only if the parent entity is in a consistent state)
  236. $rs ||= _process(
  237. 'Mail',
  238. "
  239. SELECT
  240. mail_id AS id, mail_addr AS name, status AS status
  241. FROM
  242. mail_users
  243. INNER JOIN
  244. domain USING(domain_id)
  245. WHERE
  246. status IN ('toadd', 'tochange', 'toenable', 'todelete', 'todisable')
  247. AND
  248. domain_status IN('ok', 'todelete', 'disabled')
  249. ORDER BY
  250. mail_id ASC
  251. "
  252. );
  253. # Process toadd|tochange|todelete Htusers tasks
  254. # (for each entitty, process only if the parent entity is in a consistent state)
  255. $rs ||= _process(
  256. 'Htusers',
  257. "
  258. SELECT
  259. id, CONCAT(uname, ':', id) AS name, status
  260. FROM
  261. htaccess_users
  262. INNER JOIN
  263. domain ON(domain_id = dmn_id)
  264. WHERE
  265. status IN ('toadd', 'tochange', 'todelete')
  266. AND
  267. domain_status = 'ok'
  268. ORDER BY
  269. id ASC
  270. "
  271. );
  272. # Process toadd|tochange|todelete Htgroups tasks
  273. # (for each entitty, process only if the parent entity is in a consistent state)
  274. $rs ||= _process(
  275. 'Htgroup',
  276. "
  277. SELECT
  278. id, CONCAT(ugroup, ':', id) AS name, status
  279. FROM
  280. htaccess_groups
  281. INNER JOIN
  282. domain ON(domain_id = dmn_id)
  283. WHERE
  284. status IN ('toadd', 'tochange', 'todelete')
  285. AND
  286. domain_status = 'ok'
  287. ORDER BY
  288. id ASC
  289. "
  290. );
  291. # Process toadd|tochange|todelete Htaccess tasks
  292. # (for each entitty, process only if the parent entity is in a consistent state)
  293. $rs ||= _process(
  294. 'Htaccess',
  295. "
  296. SELECT
  297. id, CONCAT(auth_name, ':', id) AS name, status
  298. FROM
  299. htaccess
  300. INNER JOIN
  301. domain ON(domain_id = dmn_id)
  302. WHERE
  303. status IN ('toadd', 'tochange', 'todelete')
  304. AND
  305. domain_status = 'ok'
  306. ORDER BY
  307. id ASC
  308. "
  309. );
  310. # Process todelete subdomain aliases tasks
  311. $rs ||= _process(
  312. 'SubAlias',
  313. "
  314. SELECT
  315. subdomain_alias_id AS id, subdomain_alias_name AS name, subdomain_alias_status AS status
  316. FROM
  317. subdomain_alias
  318. WHERE
  319. subdomain_alias_status = 'todelete'
  320. ORDER BY
  321. subdomain_alias_id ASC
  322. ",
  323. \$ipsModule
  324. );
  325. # Process todelete domain aliases tasks
  326. # (For each entity, process only if the entity do not have any direct children)
  327. $rs ||= _process(
  328. 'Alias',
  329. "
  330. SELECT DISTINCT
  331. alias_id AS id, alias_name AS name, alias_status AS status
  332. FROM
  333. domain_aliasses
  334. LEFT JOIN
  335. subdomain_alias USING(alias_id)
  336. WHERE
  337. alias_status = 'todelete'
  338. AND
  339. subdomain_alias_id IS NULL
  340. ORDER BY
  341. alias_id ASC
  342. ",
  343. \$ipsModule
  344. );
  345. # Process todelete subdomains tasks
  346. $rs ||= _process(
  347. 'Subdomain',
  348. "
  349. SELECT
  350. subdomain_id AS id, subdomain_name AS name, subdomain_status AS status
  351. FROM
  352. subdomain
  353. WHERE
  354. subdomain_status = 'todelete'
  355. ORDER BY
  356. subdomain_id ASC
  357. ",
  358. \$ipsModule
  359. );
  360. # Process todelete domains tasks
  361. # (For each entity, process only if the entity do not have any direct children)
  362. $rs ||= _process(
  363. 'Domain',
  364. "
  365. SELECT DISTINCT
  366. domain_id AS id, domain_name AS name, domain_status AS status
  367. FROM
  368. domain
  369. LEFT JOIN
  370. domain_aliasses USING(domain_id)
  371. LEFT JOIN
  372. mail_users USING(domain_id)
  373. WHERE
  374. domain_status = 'todelete'
  375. AND
  376. alias_id IS NULL
  377. AND
  378. mail_id IS NULL
  379. ORDER BY
  380. domain_id ASC
  381. ",
  382. \$ipsModule
  383. );
  384. # Process todelete users tasks
  385. # (For each entity, process only if the entity do not have any direct children)
  386. $rs ||= _process(
  387. 'User',
  388. "
  389. SELECT
  390. admin_id AS id, admin_name AS name, admin_status AS status
  391. FROM
  392. admin
  393. LEFT JOIN
  394. domain ON(domain_id = admin_id)
  395. WHERE
  396. admin_type = 'user'
  397. AND
  398. admin_status = 'todelete'
  399. AND
  400. domain_id IS NULL
  401. ORDER BY
  402. admin_id ASC
  403. "
  404. );
  405. # Process network cards tasks
  406. $rs ||= _process(
  407. 'NetCard',
  408. "
  409. SELECT
  410. ip_id AS id, ip_status AS name, ip_status AS status
  411. FROM
  412. server_ips
  413. WHERE
  414. ip_status <> 'ok'
  415. LIMIT
  416. 1
  417. "
  418. );
  419. # Process IP addresses tasks
  420. unless($rs || (! $ipsModule && $main::execmode ne 'setup')) {
  421. newDebug("Ips_module.log");
  422. eval { require Modules::Ips };
  423. unless($@) {
  424. $rs = Modules::Ips->new()->process();
  425. } else {
  426. error($@);
  427. $rs = 1;
  428. }
  429. endDebug();
  430. }
  431. # software installation BEGIN
  432. unless($rs) {
  433. my $db = iMSCP::Database->factory();
  434. my $rdata = $db->doQuery(
  435. 'software_id',
  436. "
  437. SELECT
  438. domain_id, alias_id, subdomain_id, subdomain_alias_id, software_id, path, software_prefix,
  439. db, database_user, database_tmp_pwd, install_username, install_password, install_email,
  440. software_status, software_depot, software_master_id
  441. FROM
  442. web_software_inst
  443. WHERE
  444. software_status IN ('toadd', 'todelete')
  445. ORDER BY
  446. domain_id ASC
  447. "
  448. );
  449. unless(ref $rdata eq 'HASH'){
  450. error($rdata);
  451. $rs = 1;
  452. } else {
  453. my $count = scalar keys %{$rdata};
  454. newDebug('imscp_sw_mngr_engine') if $count;
  455. for (keys %$rdata) {
  456. my (
  457. $sw_domain_id, $sw_aliasdomain_id, $sw_subdomain_id, $sw_aliassubdomain_id, $sw_software_id,
  458. $sw_path, $sw_software_prefix, $sw_database, $sw_database_user, $sw_database_tmp_pwd,
  459. $sw_install_username, $sw_install_password, $sw_install_email, $sw_software_status,
  460. $sw_software_depot, $sw_software_master_id
  461. ) = (
  462. $rdata->{$_}->{'domain_id'}, $rdata->{$_}->{'alias_id'}, $rdata->{$_}->{'subdomain_id'},
  463. $rdata->{$_}->{'subdomain_alias_id'}, $rdata->{$_}->{'software_id'}, $rdata->{$_}->{'path'},
  464. $rdata->{$_}->{'software_prefix'}, $rdata->{$_}->{'db'}, $rdata->{$_}->{'database_user'},
  465. $rdata->{$_}->{'database_tmp_pwd'}, $rdata->{$_}->{'install_username'},
  466. $rdata->{$_}->{'install_password'}, $rdata->{$_}->{'install_email'},
  467. $rdata->{$_}->{'software_status'}, $rdata->{$_}->{'software_depot'},
  468. $rdata->{$_}->{'software_master_id'}
  469. );
  470. # Encoding data to push to another script
  471. my $imscp_sw_mngr_pushstring = encode_base64(
  472. encode_json(
  473. [
  474. $sw_domain_id, $sw_software_id, $sw_path, $sw_software_prefix, $sw_database,
  475. $sw_database_user, $sw_database_tmp_pwd, $sw_install_username, $sw_install_password,
  476. $sw_install_email, $sw_software_status, $sw_software_depot, $sw_software_master_id,
  477. $sw_aliasdomain_id, $sw_subdomain_id, $sw_aliassubdomain_id
  478. ]
  479. )
  480. );
  481. my ($stdout, $stderr);
  482. $rs = execute(
  483. "$main::imscpConfig{'CMD_PERL'} $main::imscpConfig{'ENGINE_ROOT_DIR'}/imscp-sw-mngr " .
  484. "\"$imscp_sw_mngr_pushstring\"",
  485. \$stdout,
  486. \$stderr
  487. );
  488. debug($stdout) if $stdout;
  489. error($stderr) if $stderr && $rs;
  490. last if $rs;
  491. $rs = execute(
  492. "$main::imscpConfig{'CMD_RM'} -fR /tmp/sw-$sw_domain_id-$sw_software_id", \$stdout, \$stderr
  493. );
  494. debug($stdout) if $stdout;
  495. error($stderr) if $stderr && $rs;
  496. last if $rs;
  497. }
  498. endDebug() if $count;
  499. unless($rs) {
  500. $rdata = $db->doQuery(
  501. 'software_id',
  502. "
  503. SELECT
  504. software_id, reseller_id, software_archive, software_status, software_depot
  505. FROM
  506. web_software
  507. WHERE
  508. software_status = 'toadd'
  509. ORDER BY
  510. reseller_id ASC
  511. "
  512. );
  513. unless(ref $rdata eq 'HASH'){
  514. error($rdata);
  515. $rs = 1;
  516. } else {
  517. $count = scalar keys %$rdata;
  518. newDebug('imscp_pkt_mngr_engine.log') if $count;
  519. for (keys %$rdata) {
  520. my (
  521. $sw_software_id, $sw_reseller_id, $sw_software_archive, $sw_software_status,
  522. $sw_software_depot
  523. ) = (
  524. $rdata->{$_}->{'software_id'}, $rdata->{$_}->{'reseller_id'},
  525. $rdata->{$_}->{'software_archive'}, $rdata->{$_}->{'software_status'},
  526. $rdata->{$_}->{'software_depot'}
  527. );
  528. # Encoding data to push to another script
  529. my $pushstring = encode_base64(
  530. encode_json(
  531. [
  532. $sw_software_id, $sw_reseller_id, $sw_software_archive, $sw_software_status,
  533. $sw_software_depot
  534. ]
  535. )
  536. );
  537. my ($stdout, $stderr);
  538. $rs = execute(
  539. "$main::imscpConfig{'CMD_PERL'} $main::imscpConfig{'ENGINE_ROOT_DIR'}/imscp-pkt-mngr " .
  540. "\"$pushstring\"",
  541. \$stdout,
  542. \$stderr
  543. );
  544. debug($stdout) if $stdout;
  545. error($stderr) if $stderr && $rs;
  546. last if $rs;
  547. $rs = execute(
  548. "$main::imscpConfig{'CMD_RM'} -fR /tmp/sw-$sw_software_archive-$sw_software_id",
  549. \$stdout,
  550. \$stderr
  551. );
  552. debug($stdout) if $stdout;
  553. error($stderr) if $stderr && $rs;
  554. last if $rs;
  555. }
  556. }
  557. }
  558. endDebug() if $count;
  559. }
  560. }
  561. iMSCP::EventManager->getInstance()->trigger('afterDispatchRequest', $rs);
  562. $rs;
  563. }
  564. exit run();