Annotation of doc/install/linux/install.pl, revision 1.45.2.17
1.1 raeburn 1: #!/usr/bin/perl
2: # The LearningOnline Network
3: # Pre-installation script for LON-CAPA
4: #
5: # Copyright Michigan State University Board of Trustees
6: #
7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
8: #
9: # LON-CAPA is free software; you can redistribute it and/or modify
10: # it under the terms of the GNU General Public License as published by
11: # the Free Software Foundation; either version 2 of the License, or
12: # (at your option) any later version.
13: #
14: # LON-CAPA is distributed in the hope that it will be useful,
15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: # GNU General Public License for more details.
18: #
19: # You should have received a copy of the GNU General Public License
20: # along with LON-CAPA; if not, write to the Free Software
21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22: #
23: # http://www.lon-capa.org/
24: #
25:
26: use strict;
27: use File::Copy;
28: use Term::ReadKey;
29: use DBI;
1.45.2.11 raeburn 30: use File::Spec;
1.43 raeburn 31: use Cwd();
32: use File::Basename();
33: use lib File::Basename::dirname(Cwd::abs_path($0));
1.1 raeburn 34: use LCLocalization::localize;
35:
36: # ========================================================= The language handle
37:
38: my %languages = (
39: ar => 'Arabic',
40: de => 'German',
41: en => 'English',
42: es => 'Spanish (Castellan)',
43: fa => 'Persian',
44: fr => 'French',
45: he => 'Hebrew',
46: ja => 'Japanese',
47: pt => 'Portuguese',
48: ru => 'Russian',
49: tr => 'Turkish',
50: zh => 'Chinese Simplified'
51: );
52:
53: use vars qw($lh $lang);
54: $lang = 'en';
55: if (@ARGV > 0) {
56: foreach my $poss (keys(%languages)) {
57: if ($ARGV[0] eq $poss) {
58: $lang = $ARGV[0];
59: }
60: }
61: }
62:
63: &get_language_handle($lang);
64:
65: # Check user has root privs
66: if (0 != $<) {
67: print &mt('This script must be run as root.')."\n".
68: &mt('Stopping execution.')."\n";
69: exit;
70: }
71:
72:
73: # Globals: filehandle LOG is global.
74: if (!open(LOG,">>loncapa_install.log")) {
75: print &mt('Unable to open log file.')."\n".
76: &mt('Stopping execution.')."\n";
77: exit;
78: } else {
1.45.2.17! raeburn 79: print LOG '$Id: install.pl,v 1.45.2.16 2021/03/29 03:50:33 raeburn Exp $'."\n";
1.1 raeburn 80: }
81:
82: #
1.2 raeburn 83: # Helper routines and routines to establish recommended actions
1.1 raeburn 84: #
85:
86: sub get_language_handle {
87: my @languages = @_;
88: $lh=LCLocalization::localize->get_handle(@languages);
89: }
90:
91: sub mt (@) {
92: if ($lh) {
93: if ($_[0] eq '') {
94: if (wantarray) {
95: return @_;
96: } else {
97: return $_[0];
98: }
99: } else {
100: return $lh->maketext(@_);
101: }
102: } else {
103: if (wantarray) {
104: return @_;
105: } else {
106: return $_[0];
107: }
108: }
109: }
110:
111: sub texthash {
112: my (%hash) = @_;
113: foreach (keys(%hash)) {
114: $hash{$_}=&mt($hash{$_});
115: }
116: return %hash;
117: }
118:
119:
120: sub skip_if_nonempty {
121: my ($string,$error)=@_;
122: return if (! defined($error));
123: chomp($string);chomp($error);
124: if ($string ne '') {
125: print_and_log("$error\n".&mt('Stopping execution.')."\n");
126: return 1;
127: }
128: return;
129: }
130:
131: sub writelog {
132: while ($_ = shift) {
133: chomp();
134: print LOG "$_\n";
135: }
136: }
137:
138: sub print_and_log {
139: while ($_=shift) {
140: chomp();
141: print "$_\n";
142: print LOG "$_\n";
143: }
144: }
145:
146: sub get_user_selection {
147: my ($defaultrun) = @_;
148: my $do_action = 0;
149: my $choice = <STDIN>;
150: chomp($choice);
151: $choice =~ s/(^\s+|\s+$)//g;
152: my $yes = &mt('y');
153: if ($defaultrun) {
154: if (($choice eq '') || ($choice =~ /^\Q$yes\E/i)) {
155: $do_action = 1;
156: }
157: } else {
158: if ($choice =~ /^\Q$yes\E/i) {
159: $do_action = 1;
160: }
161: }
162: return $do_action;
163: }
164:
165: sub get_distro {
1.45.2.1 raeburn 166: my ($distro,$gotprereqs,$updatecmd,$packagecmd,$installnow,$unknown);
1.1 raeburn 167: $packagecmd = '/bin/rpm -q LONCAPA-prerequisites ';
1.45.2.3 raeburn 168: if (-e '/etc/oracle-release') {
169: open(IN,'</etc/oracle-release');
170: my $versionstring=<IN>;
171: chomp($versionstring);
172: close(IN);
173: if ($versionstring =~ /^Oracle Linux Server release (\d+)/) {
174: my $version = $1;
175: $distro = 'oracle'.$1;
176: $updatecmd = 'yum install LONCAPA-prerequisites';
177: $installnow = 'yum -y install LONCAPA-prerequisites';
178: }
179: } elsif (-e '/etc/redhat-release') {
1.1 raeburn 180: open(IN,'</etc/redhat-release');
181: my $versionstring=<IN>;
182: chomp($versionstring);
183: close(IN);
184: if ($versionstring =~ /^Red Hat Linux release ([\d\.]+) /) {
185: my $version = $1;
186: if ($version=~/^7\./) {
187: $distro='redhat7';
188: } elsif ($version=~/^8\./) {
189: $distro='redhat8';
190: } elsif ($version=~/^9/) {
191: $distro='redhat9';
192: }
193: } elsif ($versionstring =~ /Fedora( Core)? release ([\d\.]+) /) {
194: my $version=$2;
195: if ($version - int($version) > .9) {
196: $distro = 'fedora'.(int($version)+1);
197: } else {
198: $distro = 'fedora'.int($version);
199: }
200: $updatecmd = 'yum install LONCAPA-prerequisites';
201: $installnow = 'yum -y install LONCAPA-prerequisites';
202: } elsif ($versionstring =~ /Red Hat Enterprise Linux [AE]S release ([\d\.]+) /) {
203: $distro = 'rhes'.$1;
204: $updatecmd = 'up2date -i LONCAPA-prerequisites';
205: } elsif ($versionstring =~ /Red Hat Enterprise Linux Server release (\d+)/) {
206: $distro = 'rhes'.$1;
207: $updatecmd = 'yum install LONCAPA-prerequisites';
208: $installnow = 'yum -y install LONCAPA-prerequisites';
1.45.2.3 raeburn 209: } elsif ($versionstring =~ /Red Hat Enterprise Linux release (\d+)/) {
210: $distro = 'rhes'.$1;
211: $updatecmd = 'dnf install LONCAPA-prerequisites';
212: $installnow = 'dnf -y install LONCAPA-prerequisites';
1.45.2.13 raeburn 213: } elsif ($versionstring =~ /CentOS(?:| Linux| Stream) release (\d+)/) {
1.1 raeburn 214: $distro = 'centos'.$1;
215: $updatecmd = 'yum install LONCAPA-prerequisites';
216: $installnow = 'yum -y install LONCAPA-prerequisites';
1.22 raeburn 217: } elsif ($versionstring =~ /Scientific Linux (?:SL )?release ([\d.]+) /) {
1.1 raeburn 218: my $ver = $1;
219: $ver =~ s/\.\d+$//;
220: $distro = 'scientific'.$ver;
221: $updatecmd = 'yum install LONCAPA-prerequisites';
222: $installnow = 'yum -y install LONCAPA-prerequisites';
223: } else {
224: print &mt('Unable to interpret [_1] to determine system type.',
225: '/etc/redhat-release')."\n";
1.45.2.1 raeburn 226: $unknown = 1;
1.1 raeburn 227: }
228: } elsif (-e '/etc/SuSE-release') {
229: open(IN,'</etc/SuSE-release');
230: my $versionstring=<IN>;
231: chomp($versionstring);
232: close(IN);
233: if ($versionstring =~ /^SUSE LINUX Enterprise Server ([\d\.]+) /i) {
234: $distro='sles'.$1;
235: if ($1 >= 10) {
236: $updatecmd = 'zypper install LONCAPA-prerequisites';
237: } else {
238: $updatecmd = 'yast -i LONCAPA-prerequisites';
239: }
240: } elsif ($versionstring =~ /^SuSE Linux ([\d\.]+) /i) {
241: $distro = 'suse'.$1;
1.12 raeburn 242: $updatecmd = 'yast -i LONCAPA-prerequisites';
1.1 raeburn 243: } elsif ($versionstring =~ /^openSUSE ([\d\.]+) /i) {
244: $distro = 'suse'.$1;
245: if ($1 >= 10.3 ) {
246: $updatecmd = 'zypper install LONCAPA-prerequisites';
247: } else {
248: $updatecmd = 'yast -i LONCAPA-prerequisites';
249: }
250: } else {
251: print &mt('Unable to interpret [_1] to determine system type.',
252: '/etc/SuSE-release')."\n";
1.45.2.1 raeburn 253: $unknown = 1;
1.1 raeburn 254: }
255: } elsif (-e '/etc/issue') {
256: open(IN,'</etc/issue');
257: my $versionstring=<IN>;
258: chomp($versionstring);
259: close(IN);
260: if ($versionstring =~ /^Ubuntu (\d+)\.\d+/i) {
261: $distro = 'ubuntu'.$1;
262: $updatecmd = 'sudo apt-get install loncapa-prerequisites';
263: } elsif ($versionstring =~ /^Debian\s+GNU\/Linux\s+(\d+)\.\d+/i) {
264: $distro = 'debian'.$1;
1.45.2.1 raeburn 265: $updatecmd = 'apt-get install loncapa-prerequisites';
1.1 raeburn 266: } elsif (-e '/etc/debian_version') {
267: open(IN,'</etc/debian_version');
268: my $version=<IN>;
269: chomp($version);
270: close(IN);
271: if ($version =~ /^(\d+)\.\d+\.?\d*/) {
272: $distro='debian'.$1;
1.45.2.1 raeburn 273: $updatecmd = 'apt-get install loncapa-prerequisites';
1.1 raeburn 274: } else {
275: print &mt('Unable to interpret [_1] to determine system type.',
276: '/etc/debian_version')."\n";
1.45.2.1 raeburn 277: $unknown = 1;
1.1 raeburn 278: }
1.45.2.1 raeburn 279: }
280: if ($distro ne '') {
281: $packagecmd = '/usr/bin/dpkg -l loncapa-prerequisites ';
1.1 raeburn 282: }
283: } elsif (-e '/etc/debian_version') {
284: open(IN,'</etc/debian_version');
285: my $version=<IN>;
286: chomp($version);
287: close(IN);
288: if ($version =~ /^(\d+)\.\d+\.?\d*/) {
289: $distro='debian'.$1;
290: $packagecmd = '/usr/bin/dpkg -l loncapa-prerequisites ';
291: $updatecmd = 'apt-get install loncapa-prerequisites';
292: } else {
293: print &mt('Unable to interpret [_1] to determine system type.',
294: '/etc/debian_version')."\n";
1.45.2.1 raeburn 295: $unknown = 1;
296: }
297: }
298: if (($distro eq '') && (!$unknown)) {
299: if (-e '/etc/os-release') {
300: if (open(IN,'<','/etc/os-release')) {
301: my ($id,$version);
302: while(<IN>) {
303: chomp();
304: if (/^ID="(\w+)"/) {
305: $id=$1;
306: } elsif (/^VERSION_ID="([\d\.]+)"/) {
307: $version=$1;
308: }
309: }
310: close(IN);
311: if ($id eq 'sles') {
312: my ($major,$minor) = split(/\./,$version);
313: if ($major =~ /^\d+$/) {
314: $distro = $id.$major;
315: $updatecmd = 'zypper install LONCAPA-prerequisites';
316: }
317: }
318: }
319: if ($distro eq '') {
320: print &mt('Unable to interpret [_1] to determine system type.',
321: '/etc/os-release')."\n";
322: $unknown = 1;
323: }
324: } else {
1.45.2.3 raeburn 325: print &mt('Unknown installation: expecting a debian, ubuntu, suse, sles, redhat, fedora, scientific linux, or oracle linux system.')."\n";
1.1 raeburn 326: }
327: }
328: return ($distro,$packagecmd,$updatecmd,$installnow);
329: }
330:
331: sub check_prerequisites {
332: my ($packagecmd,$distro) = @_;
333: my $gotprereqs;
334: if ($packagecmd ne '') {
335: if (open(PIPE,"$packagecmd|")) {
336: if ($distro =~ /^(debian|ubuntu)/) {
337: my @lines = <PIPE>;
338: chomp(@lines);
339: foreach my $line (@lines) {
340: if ($line =~ /^ii\s+loncapa-prerequisites\s+([\w\.]+)/) {
341: $gotprereqs = $1;
342: }
343: }
344: } else {
345: my $line = <PIPE>;
346: chomp($line);
1.8 raeburn 347: if ($line =~ /^LONCAPA\-prerequisites\-([\d\-]+)\.(?:[.\w]+)$/) {
1.1 raeburn 348: $gotprereqs = $1;
349: }
350: }
351: close(PIPE);
352: } else {
353: print &mt('Error: could not determine if LONCAPA-prerequisites package is installed')."\n";
354: }
355: }
356: return $gotprereqs;
357: }
358:
1.6 raeburn 359: sub check_locale {
360: my ($distro) = @_;
1.45.2.7 raeburn 361: my ($fh,$langvar,$command,$earlyout);
1.8 raeburn 362: $langvar = 'LANG';
1.6 raeburn 363: if ($distro =~ /^(ubuntu|debian)/) {
364: if (!open($fh,"</etc/default/locale")) {
365: print &mt('Failed to open: [_1], default locale not checked.',
366: '/etc/default/locale');
1.45.2.7 raeburn 367: $earlyout = 1;
1.6 raeburn 368: }
1.45.2.1 raeburn 369: } elsif ($distro =~ /^(suse|sles)(\d+)/) {
370: if (($1 eq 'sles') && ($2 >= 15)) {
371: if (!open($fh,"</etc/locale.conf")) {
372: print &mt('Failed to open: [_1], default locale not checked.',
373: '/etc/locale.conf');
1.45.2.7 raeburn 374: $earlyout = 1;
1.45.2.1 raeburn 375: }
376: } else {
377: if (!open($fh,"</etc/sysconfig/language")) {
378: print &mt('Failed to open: [_1], default locale not checked.',
379: '/etc/sysconfig/language');
1.45.2.7 raeburn 380: $earlyout = 1;
1.45.2.1 raeburn 381: }
382: $langvar = 'RC_LANG';
1.8 raeburn 383: }
1.24 raeburn 384: } elsif ($distro =~ /^fedora(\d+)/) {
385: if ($1 >= 18) {
386: if (!open($fh,"</etc/locale.conf")) {
387: print &mt('Failed to open: [_1], default locale not checked.',
388: '/etc/locale.conf');
1.45.2.7 raeburn 389: $earlyout = 1;
1.24 raeburn 390: }
391: } elsif (!open($fh,"</etc/sysconfig/i18n")) {
392: print &mt('Failed to open: [_1], default locale not checked.',
393: '/etc/sysconfig/i18n');
1.45.2.7 raeburn 394: $earlyout = 1;
1.24 raeburn 395: }
1.45.2.3 raeburn 396: } elsif ($distro =~ /^(?:rhes|centos|scientific|oracle)(\d+)/) {
1.29 raeburn 397: if ($1 >= 7) {
398: if (!open($fh,"</etc/locale.conf")) {
399: print &mt('Failed to open: [_1], default locale not checked.',
400: '/etc/locale.conf');
1.45.2.7 raeburn 401: $earlyout = 1;
1.29 raeburn 402: }
403: } elsif (!open($fh,"</etc/sysconfig/i18n")) {
404: print &mt('Failed to open: [_1], default locale not checked.',
405: '/etc/sysconfig/i18n');
1.45.2.7 raeburn 406: $earlyout = 1;
1.29 raeburn 407: }
1.6 raeburn 408: } else {
409: if (!open($fh,"</etc/sysconfig/i18n")) {
410: print &mt('Failed to open: [_1], default locale not checked.',
411: '/etc/sysconfig/i18n');
1.45.2.7 raeburn 412: $earlyout = 1;
1.6 raeburn 413: }
414: }
1.45.2.7 raeburn 415: return if ($earlyout);
1.6 raeburn 416: my @data = <$fh>;
417: chomp(@data);
418: foreach my $item (@data) {
1.25 raeburn 419: if ($item =~ /^\Q$langvar\E=\"?([^\"]*)\"?/) {
1.6 raeburn 420: my $default = $1;
421: if ($default ne 'en_US.UTF-8') {
422: if ($distro =~ /^debian/) {
1.25 raeburn 423: $command = 'locale-gen en_US.UTF-8'."\n".
424: 'update-locale LANG=en_US.UTF-8';
1.6 raeburn 425: } elsif ($distro =~ /^ubuntu/) {
1.25 raeburn 426: $command = 'sudo locale-gen en_US.UTF-8'."\n".
427: 'sudo update-locale LANG=en_US.UTF-8';
1.7 raeburn 428: } elsif ($distro =~ /^(suse|sles)/) {
1.45.2.3 raeburn 429: $command = 'yast language';
430: } elsif (-e '/usr/bin/system-config-language') {
1.6 raeburn 431: $command = 'system-config-language';
1.45.2.3 raeburn 432: } elsif (-e '/usr/bin/localectl') {
1.45.2.4 raeburn 433: $command = '/usr/bin/localectl set-locale LANG=en_US.UTF-8';
1.45.2.3 raeburn 434: } else {
435: $command = 'No standard command found';
1.6 raeburn 436: }
437: }
438: last;
439: }
440: }
441: close($fh);
442: return $command;
443: }
444:
1.1 raeburn 445: sub check_required {
446: my ($instdir,$dsn) = @_;
447: my ($distro,$packagecmd,$updatecmd,$installnow) = &get_distro();
448: if ($distro eq '') {
449: return;
450: }
451: my $gotprereqs = &check_prerequisites($packagecmd,$distro);
452: if ($gotprereqs eq '') {
1.22 raeburn 453: return ($distro,$gotprereqs,'',$packagecmd,$updatecmd);
1.6 raeburn 454: }
455: my $localecmd = &check_locale($distro);
456: unless ($localecmd eq '') {
457: return ($distro,$gotprereqs,$localecmd);
1.1 raeburn 458: }
1.45.2.9 raeburn 459: my ($mysqlon,$mysqlsetup,$mysqlrestart,$dbh,$has_pass,$mysql_unix_socket,$has_lcdb,
460: %recommended,$downloadstatus,$filetouse,$production,$testing,$apachefw,
1.45.2.12 raeburn 461: $tostop,$uses_systemctl,$mysql_has_wwwuser);
1.1 raeburn 462: my $wwwuid = &uid_of_www();
463: my $wwwgid = getgrnam('www');
464: if (($wwwuid eq '') || ($wwwgid eq '')) {
465: $recommended{'wwwuser'} = 1;
466: }
467: unless( -e "/usr/local/sbin/pwauth") {
468: $recommended{'pwauth'} = 1;
469: }
470: $mysqlon = &check_mysql_running($distro);
471: if ($mysqlon) {
1.45.2.14 raeburn 472: ($mysqlsetup,$has_pass,$dbh,$mysql_has_wwwuser,$mysql_unix_socket) =
1.45.2.12 raeburn 473: &check_mysql_setup($instdir,$dsn,$distro);
1.34 raeburn 474: if ($mysqlsetup eq 'needsrestart') {
475: $mysqlrestart = '';
476: if ($distro eq 'ubuntu') {
477: $mysqlrestart = 'sudo ';
478: }
479: $mysqlrestart .= 'service mysql restart';
480: return ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,$mysqlrestart);
1.1 raeburn 481: } else {
1.34 raeburn 482: if ($mysqlsetup eq 'noroot') {
1.1 raeburn 483: $recommended{'mysqlperms'} = 1;
1.34 raeburn 484: } else {
485: unless ($mysql_has_wwwuser) {
486: $recommended{'mysqlperms'} = 1;
487: }
488: }
489: if ($dbh) {
490: $has_lcdb = &check_loncapa_mysqldb($dbh);
491: }
492: unless ($has_lcdb) {
493: $recommended{'mysql'} = 1;
1.1 raeburn 494: }
495: }
496: }
1.5 raeburn 497: ($recommended{'firewall'},$apachefw) = &chkfirewall($distro);
1.35 raeburn 498: ($recommended{'runlevels'},$tostop,$uses_systemctl) = &chkconfig($distro,$instdir);
1.1 raeburn 499: $recommended{'apache'} = &chkapache($distro,$instdir);
500: $recommended{'stopsrvcs'} = &chksrvcs($distro,$tostop);
501: ($recommended{'download'},$downloadstatus,$filetouse,$production,$testing)
1.45.2.16 raeburn 502: = &need_download($distro,$instdir);
1.6 raeburn 503: return ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,
1.45.2.9 raeburn 504: $mysqlrestart,\%recommended,$dbh,$has_pass,$mysql_unix_socket,
505: $has_lcdb,$downloadstatus,$filetouse,$production,$testing,$apachefw,
506: $uses_systemctl);
1.1 raeburn 507: }
508:
509: sub check_mysql_running {
510: my ($distro) = @_;
1.23 raeburn 511: my $use_systemctl;
1.1 raeburn 512: my $mysqldaemon ='mysqld';
513: if ($distro =~ /^(suse|sles|debian|ubuntu)/) {
514: $mysqldaemon = 'mysql';
515: }
1.6 raeburn 516: my $process = 'mysqld_safe';
517: my $proc_owner = 'root';
518: if ($distro =~ /^ubuntu(\w+)/) {
519: if ($1 >= 10) {
520: $process = 'mysqld';
521: $proc_owner = 'mysql';
522: }
1.35 raeburn 523: } elsif ($distro =~ /^fedora(\d+)/) {
1.23 raeburn 524: if ($1 >= 16) {
525: $process = 'mysqld';
526: $proc_owner = 'mysql';
527: $use_systemctl = 1;
528: }
1.39 raeburn 529: if ($1 >= 19) {
1.37 raeburn 530: $mysqldaemon ='mariadb';
531: }
1.45.2.17! raeburn 532: if ($1 >= 34) {
! 533: $process = 'mariadb';
! 534: }
1.45.2.3 raeburn 535: } elsif ($distro =~ /^(?:centos|rhes|scientific|oracle)(\d+)/) {
1.29 raeburn 536: if ($1 >= 7) {
537: $mysqldaemon ='mariadb';
538: $process = 'mysqld';
539: $proc_owner = 'mysql';
540: $use_systemctl = 1;
541: }
1.35 raeburn 542: } elsif ($distro =~ /^sles(\d+)/) {
543: if ($1 >= 12) {
544: $use_systemctl = 1;
1.42 raeburn 545: $proc_owner = 'mysql';
546: $process = 'mysqld';
1.35 raeburn 547: }
1.45.2.1 raeburn 548: if ($1 >= 15) {
549: $mysqldaemon ='mariadb';
550: }
1.35 raeburn 551: } elsif ($distro =~ /^suse(\d+)/) {
552: if ($1 >= 13) {
553: $use_systemctl = 1;
554: }
1.29 raeburn 555: }
1.35 raeburn 556: if (open(PIPE,"ps -ef |grep $process |grep ^$proc_owner |grep -v grep 2>&1 |")) {
1.1 raeburn 557: my $status = <PIPE>;
558: close(PIPE);
559: chomp($status);
1.6 raeburn 560: if ($status =~ /^\Q$proc_owner\E\s+\d+\s+/) {
1.1 raeburn 561: print_and_log(&mt('MySQL is running.')."\n");
562: return 1;
563: } else {
1.23 raeburn 564: if ($use_systemctl) {
565: system("/bin/systemctl start $mysqldaemon.service >/dev/null 2>&1 ");
566: } else {
567: system("/etc/init.d/$mysqldaemon start >/dev/null 2>&1 ");
568: }
1.1 raeburn 569: print_and_log(&mt('Waiting for MySQL to start.')."\n");
570: sleep 5;
1.12 raeburn 571: if (open(PIPE,"ps -ef |grep $process |grep -v grep 2>&1 |")) {
572: $status = <PIPE>;
1.1 raeburn 573: close(PIPE);
574: chomp($status);
1.12 raeburn 575: if ($status =~ /^\Q$proc_owner\E\s+\d+\s+/) {
1.1 raeburn 576: print_and_log(&mt('MySQL is running.')."\n");
577: return 1;
578: } else {
1.12 raeburn 579: print_and_log(&mt('Still waiting for MySQL to start.')."\n");
580: sleep 5;
581: if (open(PIPE,"ps -ef |grep $process |grep -v grep 2>&1 |")) {
582: $status = <PIPE>;
583: close(PIPE);
584: chomp($status);
585: if ($status =~ /^\Q$proc_owner\E\s+\d+\s+/) {
586: print_and_log(&mt('MySQL is running.')."\n");
587: return 1;
588: } else {
589: print_and_log(&mt('Given up waiting for MySQL to start.')."\n");
590: }
591: }
1.1 raeburn 592: }
593: }
594: }
595: } else {
596: print &mt('Could not determine if MySQL is running.')."\n";
597: }
598: return;
599: }
600:
601: sub chkconfig {
1.8 raeburn 602: my ($distro,$instdir) = @_;
1.23 raeburn 603: my (%needfix,%tostop,%uses_systemctl);
1.1 raeburn 604: my $checker_bin = '/sbin/chkconfig';
1.23 raeburn 605: my $sysctl_bin = '/bin/systemctl';
1.6 raeburn 606: my %daemon = (
607: mysql => 'mysqld',
608: apache => 'httpd',
609: cups => 'cups',
610: ntp => 'ntpd',
611: memcached => 'memcached',
612: );
1.1 raeburn 613: my @runlevels = qw/3 4 5/;
614: my @norunlevels = qw/0 1 6/;
615: if ($distro =~ /^(suse|sles)/) {
616: @runlevels = qw/3 5/;
617: @norunlevels = qw/0 2 1 6/;
1.6 raeburn 618: $daemon{'mysql'} = 'mysql';
619: $daemon{'apache'} = 'apache2';
1.8 raeburn 620: $daemon{'ntp'} = 'ntp';
1.1 raeburn 621: if ($distro =~ /^(suse|sles)9/) {
1.6 raeburn 622: $daemon{'apache'} = 'apache';
1.1 raeburn 623: }
1.35 raeburn 624: if ($distro =~ /^(suse|sles)([\d\.]+)/) {
625: my $name = $1;
626: my $num = $2;
627: if ($num > 11) {
1.26 raeburn 628: $uses_systemctl{'apache'} = 1;
1.35 raeburn 629: if (($name eq 'sles') || ($name eq 'suse' && $num >= 13.2)) {
630: $uses_systemctl{'mysql'} = 1;
631: $uses_systemctl{'ntp'} = 1;
632: $uses_systemctl{'cups'} = 1;
633: $uses_systemctl{'memcached'} = 1;
1.45.2.1 raeburn 634: if (($name eq 'sles') && ($num >= 15)) {
635: $daemon{'ntp'} = 'chronyd';
636: $daemon{'mysql'} = 'mariadb';
637: } else {
638: $daemon{'ntp'} = 'ntpd';
639: }
1.35 raeburn 640: }
1.26 raeburn 641: }
642: }
1.6 raeburn 643: } elsif ($distro =~ /^(?:debian|ubuntu)(\d+)/) {
644: my $version = $1;
1.1 raeburn 645: @runlevels = qw/2 3 4 5/;
646: @norunlevels = qw/0 1 6/;
1.44 raeburn 647: if (($distro =~ /^ubuntu/) && ($version <= 16)) {
648: $checker_bin = '/usr/sbin/sysv-rc-conf';
649: } else {
650: $uses_systemctl{'ntp'} = 1;
651: $uses_systemctl{'mysql'} = 1;
652: $uses_systemctl{'apache'} = 1;
653: $uses_systemctl{'memcached'} = 1;
654: $uses_systemctl{'cups'} = 1;
655: }
1.6 raeburn 656: $daemon{'mysql'} = 'mysql';
657: $daemon{'apache'} = 'apache2';
658: $daemon{'ntp'} = 'ntp';
659: if (($distro =~ /^ubuntu/) && ($version <= 8)) {
660: $daemon{'cups'} = 'cupsys';
661: }
1.45.2.6 raeburn 662: if (($distro =~ /^ubuntu/) && ($version >= 18)) {
663: $daemon{'ntp'} = 'chrony';
664: }
1.26 raeburn 665: } elsif ($distro =~ /^fedora(\d+)/) {
1.23 raeburn 666: my $version = $1;
667: if ($version >= 15) {
668: $uses_systemctl{'ntp'} = 1;
669: }
670: if ($version >= 16) {
671: $uses_systemctl{'mysql'} = 1;
672: $uses_systemctl{'apache'} = 1;
1.35 raeburn 673: $uses_systemctl{'memcached'} = 1;
674: $uses_systemctl{'cups'} = 1;
1.23 raeburn 675: }
1.39 raeburn 676: if ($version >= 19) {
1.37 raeburn 677: $daemon{'mysql'} = 'mariadb';
678: }
1.45.2.5 raeburn 679: if ($version >= 26) {
680: $daemon{'ntp'} = 'chronyd';
681: }
1.45.2.3 raeburn 682: } elsif ($distro =~ /^(?:centos|rhes|scientific|oracle)(\d+)/) {
1.29 raeburn 683: my $version = $1;
684: if ($version >= 7) {
685: $uses_systemctl{'ntp'} = 1;
686: $uses_systemctl{'mysql'} = 1;
687: $uses_systemctl{'apache'} = 1;
1.35 raeburn 688: $uses_systemctl{'memcached'} = 1;
689: $uses_systemctl{'cups'} = 1;
1.30 raeburn 690: $daemon{'mysql'} = 'mariadb';
1.29 raeburn 691: }
1.45.2.3 raeburn 692: if (($version >= 8) || ($distro eq 'oracle7')) {
693: $daemon{'ntp'} = 'chronyd';
694: }
1.1 raeburn 695: }
1.23 raeburn 696: my $nocheck;
1.1 raeburn 697: if (! -x $checker_bin) {
1.23 raeburn 698: if ($uses_systemctl{'mysql'} && $uses_systemctl{'apache'}) {
699: if (! -x $sysctl_bin) {
700: $nocheck = 1;
701: }
702: } else {
703: $nocheck = 1;
704: }
705: }
706: if ($nocheck) {
1.6 raeburn 707: print &mt('Could not check runlevel status for MySQL or Apache')."\n";
1.1 raeburn 708: return;
709: }
710: my $rlstr = join('',@runlevels);
711: my $nrlstr = join('',@norunlevels);
1.23 raeburn 712:
1.6 raeburn 713: foreach my $type ('apache','mysql','ntp','cups','memcached') {
714: my $service = $daemon{$type};
1.23 raeburn 715: if ($uses_systemctl{$type}) {
1.35 raeburn 716: if (($type eq 'memcached') || ($type eq 'cups')) {
717: if (-l "/etc/systemd/system/multi-user.target.wants/$service.service") {
718: $tostop{$type} = 1;
719: }
720: } else {
721: if (!-l "/etc/systemd/system/multi-user.target.wants/$service.service") {
722: $needfix{$type} = "systemctl enable $service.service";
723: }
1.23 raeburn 724: }
725: } else {
726: my $command = $checker_bin.' --list '.$service.' 2>/dev/null';
1.35 raeburn 727: if ($type eq 'cups') {
1.23 raeburn 728: if ($distro =~ /^(?:debian|ubuntu)(\d+)/) {
729: my $version = $1;
730: if (($distro =~ /^ubuntu/) && ($version <= 8)) {
731: $command = $checker_bin.' --list cupsys 2>/dev/null';
1.19 raeburn 732: }
733: }
734: }
1.23 raeburn 735: my $results = `$command`;
736: my $tofix;
737: if ($results eq '') {
738: if (($type eq 'apache') || ($type eq 'mysql') || ($type eq 'ntp')) {
739: if ($distro =~ /^(debian|ubuntu)/) {
740: $tofix = "update-rc.d $type defaults";
741: } else {
742: $tofix = "$checker_bin --add $service\n";
743: }
1.6 raeburn 744: }
1.23 raeburn 745: } else {
746: my %curr_runlevels;
747: for (my $rl=0; $rl<=6; $rl++) {
748: if ($results =~ /$rl:on/) { $curr_runlevels{$rl}++; }
749: }
750: if (($type eq 'apache') || ($type eq 'mysql') || ($type eq 'ntp')) {
751: my $warning;
752: foreach my $rl (@runlevels) {
753: if (!exists($curr_runlevels{$rl})) {
754: $warning = 1;
755: }
756: }
757: if ($warning) {
758: $tofix = "$checker_bin --level $rlstr $service on\n";
759: }
760: } elsif (keys(%curr_runlevels) > 0) {
761: $tostop{$type} = 1;
1.1 raeburn 762: }
763: }
1.23 raeburn 764: if ($tofix) {
765: $needfix{$type} = $tofix;
1.1 raeburn 766: }
1.5 raeburn 767: }
1.1 raeburn 768: }
769: if ($distro =~ /^(suse|sles)([\d\.]+)$/) {
770: my $name = $1;
771: my $version = $2;
772: my ($major,$minor);
773: if ($name eq 'suse') {
774: ($major,$minor) = split(/\./,$version);
775: } else {
776: $major = $version;
777: }
1.45.2.1 raeburn 778: if (($major > 10) && ($major <= 13)) {
1.8 raeburn 779: if (&check_SuSEfirewall2_setup($instdir)) {
780: $needfix{'insserv'} = 1;
781: }
1.1 raeburn 782: }
783: }
1.35 raeburn 784: return (\%needfix,\%tostop,\%uses_systemctl);
1.1 raeburn 785: }
786:
1.45.2.1 raeburn 787: sub uses_firewalld {
788: my ($distro) = @_;
1.45.2.3 raeburn 789: my ($inuse,$checkfirewalld,$zone);
1.45.2.1 raeburn 790: if ($distro =~ /^(suse|sles)([\d\.]+)$/) {
791: if (($1 eq 'sles') && ($2 >= 15)) {
792: $checkfirewalld = 1;
793: }
794: } elsif ($distro =~ /^fedora(\d+)$/) {
795: if ($1 >= 18) {
796: $checkfirewalld = 1;
797: }
1.45.2.3 raeburn 798: } elsif ($distro =~ /^(?:centos|rhes|scientific|oracle)(\d+)/) {
1.45.2.1 raeburn 799: if ($1 >= 7) {
800: $checkfirewalld = 1;
801: }
802: }
803: if ($checkfirewalld) {
804: my ($loaded,$active);
1.45.2.15 raeburn 805: if (open(PIPE,"systemctl status firewalld 2>/dev/null |")) {
1.45.2.1 raeburn 806: while (<PIPE>) {
807: chomp();
808: if (/^\s*Loaded:\s+(\w+)/) {
809: $loaded = $1;
810: }
1.45.2.15 raeburn 811: if (/^\s*Active:\s+(\w+)/) {
1.45.2.1 raeburn 812: $active = $1;
813: }
814: }
815: close(PIPE);
816: }
817: if (($loaded eq 'loaded') || ($active eq 'active')) {
818: $inuse = 1;
1.45.2.3 raeburn 819: my $cmd = 'firewall-cmd --get-default-zone';
820: if (open(PIPE,"$cmd |")) {
821: my $result = <PIPE>;
822: chomp($result);
823: close(PIPE);
824: if ($result =~ /^\w+$/) {
825: $zone = $result;
826: }
827: }
1.45.2.1 raeburn 828: }
829: }
1.45.2.3 raeburn 830: return ($inuse,$zone);
1.45.2.1 raeburn 831: }
832:
1.1 raeburn 833: sub chkfirewall {
1.5 raeburn 834: my ($distro) = @_;
1.1 raeburn 835: my $configfirewall = 1;
836: my %ports = (
837: http => 80,
838: https => 443,
839: );
1.5 raeburn 840: my %activefw;
1.45.2.3 raeburn 841: my ($firewalld,$zone) = &uses_firewalld($distro);
842: if ($firewalld) {
843: my %current;
844: if (open(PIPE,'firewall-cmd --permanent --zone='.$zone.' --list-services |')) {
845: my $svc = <PIPE>;
846: close(PIPE);
847: chomp($svc);
848: map { $current{$_} = 1; } (split(/\s+/,$svc));
849: }
850: if ($current{'http'} && $current{'https'}) {
851: $configfirewall = 0;
852: }
853: } else {
854: if (&firewall_is_active()) {
1.45.2.1 raeburn 855: my $iptables = &get_pathto_iptables();
856: if ($iptables eq '') {
857: print &mt('Firewall not checked as path to iptables not determined.')."\n";
858: } else {
859: my @fwchains = &get_fw_chains($iptables,$distro);
860: if (@fwchains) {
861: foreach my $service ('http','https') {
862: foreach my $fwchain (@fwchains) {
863: if (&firewall_is_port_open($iptables,$fwchain,$ports{$service})) {
864: $activefw{$service} = 1;
865: last;
866: }
1.1 raeburn 867: }
868: }
1.45.2.1 raeburn 869: if ($activefw{'http'}) {
870: $configfirewall = 0;
871: }
872: } else {
873: print &mt('Firewall not checked as iptables Chains not identified.')."\n";
1.1 raeburn 874: }
875: }
1.45.2.3 raeburn 876: } else {
877: print &mt('Firewall not enabled.')."\n";
1.1 raeburn 878: }
879: }
1.5 raeburn 880: return ($configfirewall,\%activefw);
1.1 raeburn 881: }
882:
883: sub chkapache {
884: my ($distro,$instdir) = @_;
885: my $fixapache = 1;
1.28 raeburn 886: if ($distro =~ /^(debian|ubuntu)(\d+)$/) {
887: my $distname = $1;
888: my $version = $2;
1.33 raeburn 889: my ($stdconf,$stdsite);
890: if (($distname eq 'ubuntu') && ($version > 12)) {
891: $stdconf = "$instdir/debian-ubuntu/ubuntu14/loncapa_conf";
892: $stdsite = "$instdir/debian-ubuntu/ubuntu14/loncapa_sites";
893: } else {
894: $stdconf = "$instdir/debian-ubuntu/loncapa";
895: }
896: if (!-e $stdconf) {
1.1 raeburn 897: $fixapache = 0;
898: print &mt('Warning: No LON-CAPA Apache configuration file found for installation check.')."\n";
1.28 raeburn 899: } else {
1.33 raeburn 900: my ($configfile,$sitefile);
1.28 raeburn 901: if (($distname eq 'ubuntu') && ($version > 12)) {
1.45.2.10 raeburn 902: $sitefile = '/etc/apache2/sites-available/loncapa.conf';
903: $configfile = '/etc/apache2/conf-available/loncapa.conf';
1.33 raeburn 904: } else {
1.45.2.10 raeburn 905: $configfile = '/etc/apache2/sites-available/loncapa';
1.28 raeburn 906: }
1.33 raeburn 907: if (($configfile ne '') && (-e $configfile) && (-e $stdconf)) {
908: if (open(PIPE, "diff --brief $stdconf $configfile |")) {
1.28 raeburn 909: my $diffres = <PIPE>;
910: close(PIPE);
911: chomp($diffres);
912: unless ($diffres) {
913: $fixapache = 0;
914: }
1.1 raeburn 915: }
916: }
1.33 raeburn 917: if ((!$fixapache) && ($distname eq 'ubuntu') && ($version > 12)) {
918: if (($sitefile ne '') && (-e $sitefile) && (-e $stdsite)) {
919: if (open(PIPE, "diff --brief $stdsite $sitefile |")) {
920: my $diffres = <PIPE>;
921: close(PIPE);
922: chomp($diffres);
923: unless ($diffres) {
924: $fixapache = 0;
925: }
926: }
927: }
928: }
1.1 raeburn 929: }
1.6 raeburn 930: if (!$fixapache) {
931: foreach my $module ('headers.load','expires.load') {
932: unless (-l "/etc/apache2/mods-enabled/$module") {
933: $fixapache = 1;
934: }
935: }
936: }
1.45.2.7 raeburn 937: if ((!$fixapache) && ($distname eq 'ubuntu')) {
938: my $sitestatus = "/etc/apache2/mods-available/status.conf";
939: my $stdstatus = "$instdir/debian-ubuntu/status.conf";
940: if ((-e $stdstatus) && (-e $sitestatus)) {
941: if (open(PIPE, "diff --brief $stdstatus $sitestatus |")) {
942: my $diffres = <PIPE>;
943: close(PIPE);
944: chomp($diffres);
945: if ($diffres) {
946: $fixapache = 1;
947: }
948: }
949: }
950: }
1.45.2.1 raeburn 951: } elsif ($distro =~ /^(suse|sles)([\d\.]+)$/) {
952: my ($name,$version) = ($1,$2);
1.1 raeburn 953: my $apache = 'apache';
1.45.2.1 raeburn 954: my $conf_file = "$instdir/sles-suse/default-server.conf";
955: if ($version >= 10) {
1.8 raeburn 956: $apache = 'apache2';
1.1 raeburn 957: }
1.45.2.1 raeburn 958: if (($name eq 'sles') && ($version >= 12)) {
959: $conf_file = "$instdir/sles-suse/apache2.4/default-server.conf";
960: }
961: if (!-e $conf_file) {
1.1 raeburn 962: $fixapache = 0;
963: print &mt('Warning: No LON-CAPA Apache configuration file found for installation check.')."\n";
1.45.2.1 raeburn 964: } elsif (-e "/etc/$apache/default-server.conf") {
965: if (open(PIPE, "diff --brief $conf_file /etc/$apache/default-server.conf |")) {
1.9 raeburn 966: my $diffres = <PIPE>;
967: close(PIPE);
968: chomp($diffres);
969: unless ($diffres) {
970: $fixapache = 0;
971: }
972: }
973: }
974: } elsif ($distro eq 'rhes4') {
975: if (!-e "$instdir/rhes4/httpd.conf") {
976: $fixapache = 0;
977: print &mt('Warning: No LON-CAPA Apache configuration file found for installation check.')."\n";
978: } elsif ((-e "/etc/httpd/conf/httpd.conf") && (-e "$instdir/rhes4/httpd.conf")) {
979: if (open(PIPE, "diff --brief $instdir/rhes4/httpd.conf /etc/httpd/conf/httpd.conf |")) {
1.1 raeburn 980: my $diffres = <PIPE>;
981: close(PIPE);
982: chomp($diffres);
983: unless ($diffres) {
984: $fixapache = 0;
985: }
986: }
987: }
988: } else {
1.14 raeburn 989: my $configfile = 'httpd.conf';
1.45.2.5 raeburn 990: my $mpmfile = 'mpm.conf';
1.45.2.3 raeburn 991: if ($distro =~ /^(?:centos|rhes|scientific|oracle)(\d+)$/) {
1.29 raeburn 992: if ($1 >= 7) {
993: $configfile = 'apache2.4/httpd.conf';
994: } elsif ($1 > 5) {
1.14 raeburn 995: $configfile = 'new/httpd.conf';
996: }
997: } elsif ($distro =~ /^fedora(\d+)$/) {
1.29 raeburn 998: if ($1 > 17) {
1.45.2.5 raeburn 999: $configfile = 'apache2.4/httpd.conf';
1.29 raeburn 1000: } elsif ($1 > 10) {
1.15 raeburn 1001: $configfile = 'new/httpd.conf';
1.14 raeburn 1002: }
1003: }
1004: if (!-e "$instdir/centos-rhes-fedora-sl/$configfile") {
1.1 raeburn 1005: $fixapache = 0;
1006: print &mt('Warning: No LON-CAPA Apache configuration file found for installation check.')."\n";
1.14 raeburn 1007: } elsif ((-e "/etc/httpd/conf/httpd.conf") && (-e "$instdir/centos-rhes-fedora-sl/$configfile")) {
1008: if (open(PIPE, "diff --brief $instdir/centos-rhes-fedora-sl/$configfile /etc/httpd/conf/httpd.conf |")) {
1.1 raeburn 1009: my $diffres = <PIPE>;
1010: close(PIPE);
1011: chomp($diffres);
1012: unless ($diffres) {
1013: $fixapache = 0;
1014: }
1015: }
1016: }
1.45.2.5 raeburn 1017: if (-e "/etc/httpd/conf.modules.d/00-mpm.conf") {
1018: if (!-e "$instdir/centos-rhes-fedora-sl/$mpmfile") {
1019: print &mt('Warning: No LON-CAPA Apache MPM configuration file found for installation check.')."\n";
1020: } elsif ((-e "/etc/httpd/conf.modules.d/00-mpm.conf") && (-e "$instdir/centos-rhes-fedora-sl/$mpmfile")) {
1021: if (open(PIPE, "diff --brief $instdir/centos-rhes-fedora-sl/$mpmfile /etc/httpd/conf.modules.d/00-mpm.conf |")) {
1022: my $diffres = <PIPE>;
1023: close(PIPE);
1024: chomp($diffres);
1025: if ($diffres) {
1026: $fixapache = 1;
1027: }
1028: }
1029: }
1030: }
1.1 raeburn 1031: }
1032: return $fixapache;
1033: }
1034:
1035: sub chksrvcs {
1036: my ($distro,$tostop) = @_;
1037: my %stopsrvcs;
1038: if (ref($tostop) eq 'HASH') {
1039: %stopsrvcs = %{$tostop};
1040: }
1.6 raeburn 1041: foreach my $service ('cups','memcached') {
1.1 raeburn 1042: next if (exists($stopsrvcs{$service}));
1043: my $daemon = $service;
1044: if ($service eq 'cups') {
1045: $daemon = 'cupsd';
1046: }
1047: my $cmd = "ps -ef |grep '$daemon' |grep -v grep";
1048: if (open(PIPE,'-|',$cmd)) {
1049: my $daemonrunning = <PIPE>;
1050: chomp($daemonrunning);
1051: close(PIPE);
1052: if ($daemonrunning) {
1.12 raeburn 1053: if ($service eq 'memcached') {
1.16 raeburn 1054: my $cmd = '/usr/bin/memcached';
1055: if ($distro =~ /^(suse|sles)/) {
1056: $cmd = '/usr/sbin/memcached';
1057: }
1.12 raeburn 1058: unless ($daemonrunning =~ m{^www[^/]+\Q$cmd -m 400 -v\E$}) {
1.10 raeburn 1059: $stopsrvcs{$service} = 1;
1060: }
1061: } else {
1062: $stopsrvcs{$service} = 1;
1063: }
1.1 raeburn 1064: }
1065: }
1.10 raeburn 1066: }
1.1 raeburn 1067: return \%stopsrvcs;
1068: }
1069:
1070: sub need_download {
1.45.2.16 raeburn 1071: my ($distro,$instdir) = @_;
1.1 raeburn 1072: my $needs_download = 1;
1073: my ($production,$testing,$stdsizes) = &download_versionslist();
1.45.2.16 raeburn 1074: my ($localcurrent,$localtesting,%tarball,%localsize,%bymodtime,
1.1 raeburn 1075: %bysize,$filetouse,$downloadstatus);
1.45.2.16 raeburn 1076: if (opendir(my $dir,$instdir)) {
1.1 raeburn 1077: my (@lcdownloads,$version);
1078: foreach my $file (readdir($dir)) {
1079: if ($file =~ /^loncapa\-([\w\-.]+)\.tar\.gz$/) {
1080: $version = $1;
1081: } else {
1082: next;
1083: }
1084: if (ref($stdsizes) eq 'HASH') {
1085: if ($version eq 'current') {
1.45.2.16 raeburn 1086: my @stats = stat("$instdir/$file");
1.1 raeburn 1087: $localcurrent = $stats[7];
1.4 raeburn 1088: if ($localcurrent == $stdsizes->{$production}) {
1.1 raeburn 1089: $needs_download = 0;
1090: $filetouse = $file;
1091: }
1092: } elsif ($version eq 'testing') {
1.45.2.16 raeburn 1093: my @stats = stat("$instdir/$file");
1.1 raeburn 1094: $localtesting = $stats[7];
1.4 raeburn 1095: if ($localtesting == $stdsizes->{$testing}) {
1.1 raeburn 1096: $needs_download = 0;
1097: $filetouse = $file;
1098: }
1099: }
1100: }
1101: $tarball{$version} = $file;
1102: push(@lcdownloads,$version);
1103: }
1104: if ($needs_download) {
1105: if (@lcdownloads > 0) {
1106: foreach my $version (@lcdownloads) {
1.45.2.16 raeburn 1107: my @stats = stat("$instdir/$tarball{$version}");
1.1 raeburn 1108: my $mtime = $stats[9];
1109: $localsize{$version} = $stats[7];
1110: if ($mtime) {
1111: push(@{$bymodtime{$mtime}},$version);
1112: }
1113: if ($localsize{$version}) {
1114: push(@{$bysize{$localsize{$version}}},$version);
1115: }
1116: }
1117: if ($testing) {
1118: if (exists($localsize{$testing})) {
1119: if ($stdsizes->{$testing} == $localsize{$testing}) {
1120: $needs_download = 0;
1121: $filetouse = 'loncapa-'.$testing.'.tar.gz';
1122: }
1123: }
1124: }
1125: if ($needs_download) {
1126: if ($production) {
1127: if (exists($localsize{$production})) {
1128: if ($stdsizes->{$production} == $localsize{$production}) {
1129: $needs_download = 0;
1130: $filetouse = 'loncapa-'.$production.'.tar.gz';
1131: }
1132: }
1133: }
1134: }
1135: if ($needs_download) {
1136: my @sorted = sort { $b <=> $a } keys(%bymodtime);
1137: my $newest = $sorted[0];
1138: if (ref($bymodtime{$newest}) eq 'ARRAY') {
1139: $downloadstatus =
1.45.2.16 raeburn 1140: "Latest LON-CAPA source download in $instdir is: ".
1.1 raeburn 1141: join(',',@{$bymodtime{$newest}})." (downloaded ".
1142: localtime($newest).")\n";
1143: }
1144: } else {
1145: $downloadstatus =
1.45.2.16 raeburn 1146: "The $instdir directory already contains the latest LON-CAPA version:".
1.1 raeburn 1147: "\n".$filetouse."\n"."which can be used for installation.\n";
1148: }
1149: } else {
1.45.2.16 raeburn 1150: $downloadstatus = "The $instdir directory does not appear to contain any downloaded LON-CAPA source code files which can be used for installation.\n";
1.1 raeburn 1151: }
1152: }
1153: } else {
1.45.2.16 raeburn 1154: $downloadstatus = "Could not open $instdir directory to look for existing downloads of LON-CAPA source code.\n";
1.1 raeburn 1155: }
1156: return ($needs_download,$downloadstatus,$filetouse,$production,$testing);
1157: }
1158:
1159: sub check_mysql_setup {
1.45.2.12 raeburn 1160: my ($instdir,$dsn,$distro) = @_;
1161: my ($mysqlsetup,$has_pass,$mysql_unix_socket,$mysql_has_wwwuser);
1.1 raeburn 1162: my $dbh = DBI->connect($dsn,'root','',{'PrintError'=>0});
1.45.2.9 raeburn 1163: my ($mysqlversion,$mysqlsubver,$mysqlname) = &get_mysql_version();
1164: if (($mysqlname =~ /^MariaDB/i) && ($mysqlversion >= 10.4)) {
1165: if ($dbh) {
1166: my $sth = $dbh->prepare("SELECT Priv FROM mysql.global_priv WHERE (User = 'root' AND Host ='localhost')");
1167: $sth->execute();
1168: while (my $priv = $sth->fetchrow_array) {
1.45.2.14 raeburn 1169: if ($priv =~ /unix_socket/) {
1.45.2.9 raeburn 1170: $mysql_unix_socket = 1;
1171: last;
1172: }
1173: }
1174: $sth->finish();
1175: if ($mysql_unix_socket) {
1176: print_and_log(&mt('MariaDB using unix_socket for root access from localhost.')."\n");
1177: $mysqlsetup = 'rootok';
1.45.2.12 raeburn 1178: $mysql_has_wwwuser = &check_mysql_wwwuser($dbh);
1.45.2.9 raeburn 1179: return ($mysqlsetup,$has_pass,$dbh,$mysql_has_wwwuser,$mysql_unix_socket);
1180: }
1181: }
1182: }
1.1 raeburn 1183: if ($dbh) {
1.45.2.12 raeburn 1184: $mysqlsetup = 'noroot';
1185: if (($mysqlname !~ /^MariaDB/i) && ($mysqlversion >= 5.7)) {
1186: my $sth = $dbh->prepare("SELECT plugin from mysql.user where User='root'");
1187: $sth->execute();
1188: while (my $priv = $sth->fetchrow_array) {
1189: if ($priv =~ /auth_socket/) {
1190: $mysql_unix_socket = 1;
1191: last;
1192: }
1193: }
1194: $sth->finish();
1195: if ($mysql_unix_socket) {
1196: print_and_log(&mt('MySQL using unix_socket for root access from localhost.')."\n");
1197: $mysqlsetup = 'rootok';
1198: $mysql_has_wwwuser = &check_mysql_wwwuser($dbh);
1199: return ($mysqlsetup,$has_pass,$dbh,$mysql_has_wwwuser,$mysql_unix_socket);
1200: }
1.45.2.14 raeburn 1201: }
1.1 raeburn 1202: } elsif ($DBI::err =~ /1045/) {
1203: $has_pass = 1;
1.34 raeburn 1204: } elsif ($distro =~ /^ubuntu(\d+)$/) {
1205: my $version = $1;
1206: if ($1 > 12) {
1207: print_and_log(&mt('Restarting mysql, please be patient')."\n");
1208: if (open (PIPE, "service mysql restart 2>&1 |")) {
1209: while (<PIPE>) {
1210: print $_;
1211: }
1212: close(PIPE);
1213: }
1214: $dbh = DBI->connect($dsn,'root','',{'PrintError'=>0});
1215: if ($dbh) {
1216: $mysqlsetup = 'noroot';
1.45.2.12 raeburn 1217: $mysql_has_wwwuser = &check_mysql_wwwuser($dbh);
1.34 raeburn 1218: } elsif ($DBI::err =~ /1045/) {
1219: $has_pass = 1;
1220: } else {
1221: $mysqlsetup = 'needsrestart';
1.45.2.16 raeburn 1222: $mysql_has_wwwuser = &check_mysql_wwwuser();
1.34 raeburn 1223: return ($mysqlsetup,$has_pass,$dbh,$mysql_has_wwwuser);
1224: }
1225: }
1.1 raeburn 1226: }
1227: if ($has_pass) {
1228: print &mt('You have already set a root password for the MySQL database.')."\n";
1229: my $currpass = &get_mysql_password(&mt('Please enter the password now'));
1230: $dbh = DBI->connect($dsn,'root',$currpass,{'PrintError'=>0});
1231: if ($dbh) {
1232: $mysqlsetup = 'rootok';
1233: print_and_log(&mt('Password accepted.')."\n");
1.45.2.12 raeburn 1234: $mysql_has_wwwuser = &check_mysql_wwwuser($dbh);
1.1 raeburn 1235: } else {
1236: $mysqlsetup = 'rootfail';
1237: print_and_log(&mt('Problem accessing MySQL.')."\n");
1238: if ($DBI::err =~ /1045/) {
1239: print_and_log(&mt('Perhaps the password was incorrect?')."\n");
1240: print &mt('Try again?').' ';
1241: $currpass = &get_mysql_password(&mt('Re-enter password now'));
1242: $dbh = DBI->connect($dsn,'root',$currpass,{'PrintError'=>0});
1243: if ($dbh) {
1244: $mysqlsetup = 'rootok';
1245: print_and_log(&mt('Password accepted.')."\n");
1.45.2.12 raeburn 1246: $mysql_has_wwwuser = &check_mysql_wwwuser($dbh);
1.1 raeburn 1247: } else {
1248: if ($DBI::err =~ /1045/) {
1249: print_and_log(&mt('Incorrect password.')."\n");
1250: }
1.45.2.16 raeburn 1251: $mysql_has_wwwuser = &check_mysql_wwwuser();
1.1 raeburn 1252: }
1253: }
1254: }
1.34 raeburn 1255: } elsif ($mysqlsetup ne 'noroot') {
1.1 raeburn 1256: print_and_log(&mt('Problem accessing MySQL.')."\n");
1257: $mysqlsetup = 'rootfail';
1.45.2.16 raeburn 1258: $mysql_has_wwwuser = &check_mysql_wwwuser();
1.1 raeburn 1259: }
1.34 raeburn 1260: return ($mysqlsetup,$has_pass,$dbh,$mysql_has_wwwuser);
1.1 raeburn 1261: }
1262:
1263: sub check_mysql_wwwuser {
1.45.2.12 raeburn 1264: my ($dbh) = @_;
1.1 raeburn 1265: my $mysql_wwwuser;
1.45.2.12 raeburn 1266: if ($dbh) {
1267: $mysql_wwwuser = $dbh->selectrow_array("SELECT COUNT(User) FROM mysql.user WHERE (User = 'www' AND Host ='localhost')");
1268: } else {
1269: my $dbhn = DBI->connect("DBI:mysql:database=information_schema",'www','localhostkey',
1270: {PrintError => +0}) || return;
1271: if ($dbhn) {
1272: $mysql_wwwuser = 1;
1273: $dbhn->disconnect;
1274: }
1.1 raeburn 1275: }
1276: return $mysql_wwwuser;
1277: }
1278:
1279: sub check_loncapa_mysqldb {
1280: my ($dbh) = @_;
1281: my $has_lcdb;
1282: if (ref($dbh)) {
1283: my $sth = $dbh->prepare("SHOW DATABASES");
1284: $sth->execute();
1285: while (my $dbname = $sth->fetchrow_array) {
1286: if ($dbname eq 'loncapa') {
1287: $has_lcdb = 1;
1288: last;
1289: }
1290: }
1291: $sth->finish();
1292: }
1293: return $has_lcdb;
1294: }
1295:
1296: sub get_pathto_iptables {
1297: my $iptables;
1298: if (-e '/sbin/iptables') {
1299: $iptables = '/sbin/iptables';
1300: } elsif (-e '/usr/sbin/iptables') {
1301: $iptables = '/usr/sbin/iptables';
1302: } else {
1303: print &mt('Unable to find iptables command.')."\n";
1304: }
1305: return $iptables;
1306: }
1307:
1308: sub firewall_is_active {
1309: if (-e '/proc/net/ip_tables_names') {
1.45.2.1 raeburn 1310: if (open(PIPE,'cat /proc/net/ip_tables_names |grep filter |')) {
1311: my $status = <PIPE>;
1312: close(PIPE);
1313: chomp($status);
1314: if ($status eq 'filter') {
1315: return 1;
1316: }
1317: }
1.1 raeburn 1318: }
1.45.2.1 raeburn 1319: return 0;
1.1 raeburn 1320: }
1321:
1322: sub get_fw_chains {
1.5 raeburn 1323: my ($iptables,$distro) = @_;
1.1 raeburn 1324: my @fw_chains;
1325: my $suse_config = "/etc/sysconfig/SuSEfirewall2";
1326: my $ubuntu_config = "/etc/ufw/ufw.conf";
1327: if (-e $suse_config) {
1328: push(@fw_chains,'input_ext');
1329: } else {
1330: my @posschains;
1331: if (-e $ubuntu_config) {
1332: @posschains = ('ufw-user-input','INPUT');
1.5 raeburn 1333: } elsif ($distro =~ /^debian5/) {
1334: @posschains = ('INPUT');
1.45.2.1 raeburn 1335: } elsif ($distro =~ /^(suse|sles)(\d+)/) {
1336: @posschains = ('IN_public');
1.1 raeburn 1337: } else {
1338: @posschains = ('RH-Firewall-1-INPUT','INPUT');
1339: if (!-e '/etc/sysconfig/iptables') {
1340: if (!-e '/var/lib/iptables') {
1341: print &mt('Unable to find iptables file containing static definitions.')."\n";
1342: }
1343: push(@fw_chains,'RH-Firewall-1-INPUT');
1344: }
1345: }
1346: if ($iptables eq '') {
1347: $iptables = &get_pathto_iptables();
1348: }
1349: my %counts;
1350: if (open(PIPE,"$iptables -L -n |")) {
1351: while(<PIPE>) {
1352: foreach my $chain (@posschains) {
1353: if (/(\Q$chain\E)/) {
1354: $counts{$1} ++;
1355: }
1356: }
1357: }
1358: close(PIPE);
1359: }
1360: foreach my $fw_chain (@posschains) {
1361: if ($counts{$fw_chain}) {
1362: unless(grep(/^\Q$fw_chain\E$/,@fw_chains)) {
1363: push(@fw_chains,$fw_chain);
1364: }
1365: }
1366: }
1367: }
1368: return @fw_chains;
1369: }
1370:
1371: sub firewall_is_port_open {
1372: my ($iptables,$fw_chain,$port) = @_;
1373: # returns 1 if the firewall port is open, 0 if not.
1374: #
1375: # check if firewall is active or installed
1376: return if (! &firewall_is_active());
1377: my $count = 0;
1378: if (open(PIPE,"$iptables -L $fw_chain -n |")) {
1379: while(<PIPE>) {
1380: if (/tcp dpt\:\Q$port\E/) {
1381: $count ++;
1382: last;
1383: }
1384: }
1385: close(PIPE);
1386: } else {
1387: print &mt('Firewall status not checked: unable to run [_1].','iptables -L')."\n";
1388: }
1389: return $count;
1390: }
1391:
1392: sub get_mysql_password {
1393: my ($prompt) = @_;
1394: local $| = 1;
1395: print $prompt.': ';
1396: my $newpasswd = '';
1397: ReadMode 'raw';
1398: my $key;
1399: while(ord($key = ReadKey(0)) != 10) {
1400: if(ord($key) == 127 || ord($key) == 8) {
1401: chop($newpasswd);
1402: print "\b \b";
1403: } elsif(!ord($key) < 32) {
1404: $newpasswd .= $key;
1405: print '*';
1406: }
1407: }
1408: ReadMode 'normal';
1409: print "\n";
1410: return $newpasswd;
1411: }
1412:
1413: sub check_SuSEfirewall2_setup {
1414: my ($instdir) = @_;
1415: my $need_override = 1;
1.9 raeburn 1416: if ((-e "/etc/insserv/overrides/SuSEfirewall2_setup") && (-e "$instdir/sles-suse/SuSEfirewall2_setup")) {
1417: if (open(PIPE, "diff --brief $instdir/sles-suse/SuSEfirewall2_setup /etc/insserv/overrides/SuSEfirewall2_setup |")) {
1.1 raeburn 1418: my $diffres = <PIPE>;
1419: close(PIPE);
1420: chomp($diffres);
1421: unless ($diffres) {
1422: $need_override = 0;
1423: }
1424: }
1425: }
1426: return $need_override;
1427: }
1428:
1429: sub download_versionslist {
1430: my ($production,$testing,%sizes);
1431: if (-e "latest.txt") {
1432: unlink("latest.txt");
1433: }
1434: my $rtncode = system("wget http://install.loncapa.org/versions/latest.txt ".
1435: "> /dev/null 2>&1");
1436: if (!$rtncode) {
1437: if (open(my $fh,"<latest.txt")) {
1438: my @info = <$fh>;
1439: close($fh);
1440: foreach my $line (@info) {
1441: chomp();
1442: if ($line =~ /^\QLATEST-IS: \E([\w\-.]+):(\d+)$/) {
1443: $production = $1;
1444: $sizes{$1} = $2;
1445: } elsif ($line =~ /^LATEST-TESTING-IS: \E([\w\-.]+):(\d+)$/) {
1446: $testing = $1;
1447: $sizes{$1} = $2;
1448: }
1449: }
1450: }
1451: }
1452: return ($production,$testing,\%sizes);
1453: }
1454:
1455: #
1456: # End helper routines.
1457: # Main script starts here
1458: #
1459:
1460: print "
1461: ********************************************************************
1462:
1463: ".&mt('Welcome to LON-CAPA')."
1464:
1465: ".&mt('This script will configure your system for installation of LON-CAPA.')."
1466:
1467: ********************************************************************
1468:
1469: ".&mt('The following actions are available:')."
1470:
1.4 raeburn 1471: ".&mt('1.')." ".&mt('Create the www user/group.')."
1.1 raeburn 1472: ".&mt('This is the user/group ownership under which Apache child processes run.')."
1473: ".&mt('It also owns most directories within the /home/httpd directory.')."
1474: ".&mt('This directory is where most LON-CAPA files and directories are stored.')."
1.4 raeburn 1475: ".&mt('2.')." ".&mt('Install the package LON-CAPA uses to authenticate users.')."
1476: ".&mt('3.')." ".&mt('Set-up the MySQL database.')."
1477: ".&mt('4.')." ".&mt('Set-up MySQL permissions.')."
1478: ".&mt('5.')." ".&mt('Configure Apache web server.')."
1479: ".&mt('6.')." ".&mt('Configure start-up of services.')."
1480: ".&mt('7.')." ".&mt('Check firewall settings.')."
1481: ".&mt('8.')." ".&mt('Stop services not used by LON-CAPA,')."
1.1 raeburn 1482: ".&mt('i.e., services for a print server: [_1] daemon.',"'cups'")."
1.4 raeburn 1483: ".&mt('9.')." ".&mt('Download LON-CAPA source code in readiness for installation.')."
1.1 raeburn 1484:
1485: ".&mt('Typically, you will run this script only once, when you first install LON-CAPA.')."
1486:
1487: ".&mt('The script will analyze your system to determine which actions are recommended.')."
1488: ".&mt('The script will then prompt you to choose the actions you would like taken.')."
1489:
1490: ".&mt('For each the recommended action will be selected if you hit Enter/Return.')."
1491: ".&mt('To override the default, type the lower case option from the two options listed.')."
1492: ".&mt('So, if the default is "yes", ~[Y/n~] will be shown -- type n to override.')."
1493: ".&mt('Whereas if the default is "no", ~[y/N~] will be shown -- type y to override.')."
1494:
1495: ".&mt('To accept the default, simply hit Enter/Return on your keyboard.')."
1496: ".&mt('Otherwise type: y or n then hit the Enter/Return key.')."
1497:
1498: ".&mt('Once a choice has been entered for all nine actions, required changes will be made.')."
1499: ".&mt('Feedback will be displayed on screen, and also stored in: [_1].','loncapa_install.log')."
1500:
1501: ".&mt('Continue? ~[Y/n~] ');
1502:
1503: my $go_on = &get_user_selection(1);
1504: if (!$go_on) {
1505: exit;
1506: }
1507:
1508: my $instdir = `pwd`;
1509: chomp($instdir);
1510:
1511: my %callsub;
1512: my @actions = ('wwwuser','pwauth','mysql','mysqlperms','apache',
1513: 'runlevels','firewall','stopsrvcs','download');
1514: my %prompts = &texthash(
1515: wwwuser => "Create the 'www' user?",
1516: pwauth => 'Install the package LON-CAPA uses to authenticate users?',
1517: mysql => 'Set-up the MySQL database?',
1518: mysqlperms => 'Set-up MySQL permissions?',
1519: apache => 'Configure Apache web server?',
1520: runlevels => 'Set overrides for start-up order of services?',
1521: firewall => 'Configure firewall settings for Apache',
1522: stopsrvcs => 'Stop extra services not required on a LON-CAPA server?',
1523: download => 'Download LON-CAPA source code in readiness for installation?',
1524: );
1525:
1526: print "\n".&mt('Checking system status ...')."\n";
1527:
1528: my $dsn = "DBI:mysql:database=mysql";
1.34 raeburn 1529: my ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,$mysqlrestart,
1.45.2.9 raeburn 1530: $recommended,$dbh,$has_pass,$mysql_unix_socket,$has_lcdb,$downloadstatus,
1531: $filetouse,$production,$testing,$apachefw,$uses_systemctl) = &check_required($instdir,$dsn);
1.1 raeburn 1532: if ($distro eq '') {
1533: print "\n".&mt('Linux distribution could not be verified as a supported distribution.')."\n".
1534: &mt('The following are supported: [_1].',
1535: 'CentOS, RedHat Enterprise, Fedora, Scientific Linux, '.
1.45.2.3 raeburn 1536: 'Oracle Linux, openSuSE, SLES, Ubuntu LTS, Debian')."\n\n".
1.1 raeburn 1537: &mt('Stopping execution.')."\n";
1538: exit;
1539: }
1.34 raeburn 1540: if ($mysqlrestart) {
1541: print "\n".&mt('The mysql daemon needs to be restarted using the following command:')."\n".
1542: $mysqlrestart."\n\n".
1543: &mt('Stopping execution of install.pl script.')."\n".
1544: &mt('Please run the install.pl script again, once you have restarted mysql.')."\n";
1545: exit;
1546: }
1.6 raeburn 1547: if ($localecmd ne '') {
1548: print "\n".&mt('Although the LON-CAPA application itself is localized for a number of different languages, the default locale language for the Linux OS on which it runs should be US English.')."\n";
1549: print "\n".&mt('Run the following command from the command line to set the default language for your OS, and then run this LON-CAPA installation set-up script again.')."\n\n".
1550: $localecmd."\n\n".
1551: &mt('Stopping execution.')."\n";
1552: exit;
1553: }
1.1 raeburn 1554: if (!$gotprereqs) {
1.12 raeburn 1555: print "\n".&mt('The LONCAPA-prerequisites package is not installed.')."\n".
1.1 raeburn 1556: &mt('The following command can be used to install the package (and dependencies):')."\n\n".
1557: $updatecmd."\n\n";
1558: if ($installnow eq '') {
1559: print &mt('Stopping execution.')."\n";
1560: exit;
1561: } else {
1562: print &mt('Run command? ~[Y/n~]');
1563: my $install_prereq = &get_user_selection(1);
1564: if ($install_prereq) {
1565: if (open(PIPE,'|-',$installnow)) {
1566: close(PIPE);
1567: $gotprereqs = &check_prerequisites($packagecmd,$distro);
1568: if (!$gotprereqs) {
1.12 raeburn 1569: print &mt('The LONCAPA-prerequisites package is not installed.')."\n".
1.1 raeburn 1570: &mt('Stopping execution.')."\n";
1571: exit;
1572: } else {
1.6 raeburn 1573: ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,
1.45.2.9 raeburn 1574: $mysqlrestart,$recommended,$dbh,$has_pass,$mysql_unix_socket,
1575: $has_lcdb,$downloadstatus,$filetouse,$production,$testing,$apachefw,
1576: $uses_systemctl) = &check_required($instdir,$dsn);
1.1 raeburn 1577: }
1578: } else {
1.12 raeburn 1579: print &mt('Failed to run command to install LONCAPA-prerequisites')."\n";
1.1 raeburn 1580: exit;
1581: }
1582: } else {
1583: print &mt('Stopping execution.')."\n";
1584: exit;
1585: }
1586: }
1587: }
1588: unless (ref($recommended) eq 'HASH') {
1589: print "\n".&mt('An error occurred determining which actions are recommended.')."\n\n".
1590: &mt('Stopping execution.')."\n";
1591: exit;
1592: }
1593:
1594: print "\n";
1595: my $num = 0;
1596: foreach my $action (@actions) {
1597: $num ++;
1598: my ($yesno,$defaultrun);
1599: if (ref($recommended) eq 'HASH') {
1.4 raeburn 1600: if (($action eq 'runlevels') || ($action eq 'stopsrvcs')) {
1.1 raeburn 1601: $yesno = '[y/N]';
1602: if (ref($recommended->{$action}) eq 'HASH') {
1603: if (keys(%{$recommended->{$action}}) > 0) {
1604: $yesno = &mt('~[Y/n~]');
1605: $defaultrun = 1;
1606: }
1607: }
1608: } else {
1609: if ($action eq 'download') {
1610: if ($downloadstatus) {
1611: print "\n$downloadstatus\n";
1612: }
1613: }
1614: if ($recommended->{$action}) {
1615: $yesno = mt('~[Y/n~]');
1616: $defaultrun = 1;
1617: } else {
1618: $yesno = &mt('~[y/N~]');
1619: }
1620: }
1621: print $num.'. '.$prompts{$action}." $yesno ";
1622: $callsub{$action} = &get_user_selection($defaultrun);
1623: }
1624: }
1625:
1626: my $lctarball = 'loncapa-current.tar.gz';
1627: my $sourcetarball = $lctarball;
1628: if ($callsub{'download'}) {
1629: my ($production,$testing,$sizes) = &download_versionslist();
1.45.2.16 raeburn 1630: my $homedir = '/root';
1631: if ($distro =~ /^ubuntu/) {
1632: if ($instdir ne $homedir) {
1633: ($homedir) = ($instdir =~ m{^(.*)/[^/]+$});
1634: }
1635: }
1.1 raeburn 1636: if ($production && $testing) {
1637: if ($production ne $testing) {
1638: print &mt('Two recent LON-CAPA releases are available: ')."\n".
1.3 raeburn 1639: &mt('1.').' '.&mt('A production release - version: [_1].',$production)."\n".
1640: &mt('2.').' '.&mt('A testing release - version: [_1].',$testing)."\n\n".
1.45.2.16 raeburn 1641: &mt("After download, the tar.gz file will be extracted into $homedir")."\n\n".
1642: &mt("Download the production release into $instdir? ~[Y/n~]");
1.1 raeburn 1643: if (&get_user_selection(1)) {
1.4 raeburn 1644: $sourcetarball = 'loncapa-'.$production.'.tar.gz';
1.45.2.16 raeburn 1645: print "$sourcetarball will be downloaded into $instdir\n";
1.1 raeburn 1646: } else {
1647: print "\n".&mt('Download the testing release? ~[Y/n~]');
1648: if (&get_user_selection(1)) {
1.4 raeburn 1649: $sourcetarball = 'loncapa-'.$testing.'.tar.gz';
1.45.2.16 raeburn 1650: print "$sourcetarball will be downloaded into $instdir\n";
1651: } else {
1652: $callsub{'download'} = 0;
1.1 raeburn 1653: }
1654: }
1655: }
1656: } elsif ($production) {
1657: print &mt('The most recent LON-CAPA release is version: [_1].',$production)."\n".
1.45.2.16 raeburn 1658: &mt("After download, the tar.gz file will be extracted into $homedir")."\n\n".
1659: &mt("Download the production release into $instdir? ~[Y/n~]");
1.1 raeburn 1660: if (&get_user_selection(1)) {
1.20 raeburn 1661: $sourcetarball = 'loncapa-'.$production.'.tar.gz';
1.45.2.16 raeburn 1662: print "$sourcetarball will be downloaded into $instdir\n";
1663: } else {
1664: $callsub{'download'} = 0;
1.1 raeburn 1665: }
1666: }
1667: } elsif ($filetouse ne '') {
1668: $sourcetarball = $filetouse;
1669: }
1670:
1671: print_and_log("\n");
1672:
1673: # Each action: report if skipping, or perform action and provide feedback.
1674: if ($callsub{'wwwuser'}) {
1675: &setup_www();
1676: } else {
1677: &print_and_log(&mt('Skipping creation of user [_1].',"'www'")."\n");
1678: }
1679:
1680: if ($callsub{'pwauth'}) {
1.4 raeburn 1681: &build_and_install_mod_auth_external($instdir);
1.1 raeburn 1682: } else {
1683: &print_and_log(&mt('Skipping [_1] installation.',"'pwauth'")."\n");
1684: }
1685:
1686: if ($callsub{'mysql'}) {
1687: if ($dbh) {
1.45.2.9 raeburn 1688: &setup_mysql($callsub{'mysqlperms'},$dbh,$has_pass,
1.45.2.15 raeburn 1689: $mysql_unix_socket,$has_lcdb,$distro);
1.1 raeburn 1690: } else {
1691: print &mt('Unable to configure MySQL because access is denied.')."\n";
1692: }
1693: } else {
1694: &print_and_log(&mt('Skipping configuration of MySQL.')."\n");
1695: if ($callsub{'mysqlperms'}) {
1696: if ($dbh) {
1.45.2.9 raeburn 1697: &setup_mysql_permissions($dbh,$has_pass,$mysql_unix_socket);
1.1 raeburn 1698: } else {
1699: print &mt('Unable to configure MySQL because access is denied.')."\n";
1700: }
1701: } else {
1702: &print_and_log(&mt('Skipping MySQL permissions setup.')."\n");
1703: }
1704: }
1705:
1706: if ($dbh) {
1707: if (!$dbh->disconnect) {
1708: &print_and_log(&mt('Failed to disconnect from MySQL:')."\n".
1709: $dbh->errstr);
1710: }
1711: }
1712:
1713: if ($callsub{'apache'}) {
1714: if ($distro =~ /^(suse|sles)/) {
1.45.2.1 raeburn 1715: ©_apache2_suseconf($instdir,$distro);
1.1 raeburn 1716: } elsif ($distro =~ /^(debian|ubuntu)/) {
1.28 raeburn 1717: ©_apache2_debconf($instdir,$distro);
1.1 raeburn 1718: } else {
1.14 raeburn 1719: ©_httpd_conf($instdir,$distro);
1.45.2.5 raeburn 1720: ©_mpm_conf($instdir,$distro);
1.1 raeburn 1721: }
1722: } else {
1723: print_and_log(&mt('Skipping configuration of Apache web server.')."\n");
1724: }
1725:
1726: if ($callsub{'runlevels'}) {
1727: my $count = 0;
1728: if (ref($recommended) eq 'HASH') {
1729: if (ref($recommended->{'runlevels'}) eq 'HASH') {
1730: foreach my $type (keys(%{$recommended->{'runlevels'}})) {
1731: next if ($type eq 'insserv');
1732: $count ++;
1733: my $command = $recommended->{'runlevels'}{$type};
1734: if ($command ne '') {
1735: print_and_log(&mt('Runlevel update command run: [_1].',$command)."\n");
1736: system($command);
1737: }
1738: }
1739: if (!$count) {
1740: print_and_log(&mt('No runlevel updates required.')."\n");
1741: }
1742: }
1743: }
1.45.2.1 raeburn 1744: if ($distro =~ /^(suse|sles)(\d+)/) {
1745: unless(($1 eq 'sles') && ($2 >= 15)) {
1746: &update_SuSEfirewall2_setup($instdir);
1747: }
1.11 raeburn 1748: }
1.1 raeburn 1749: } else {
1750: &print_and_log(&mt('Skipping setting override for start-up order of services.')."\n");
1751: }
1752:
1753: if ($callsub{'firewall'}) {
1.45.2.3 raeburn 1754: my ($firewalld,$zone) = &uses_firewalld($distro);
1755: if ($firewalld) {
1.45.2.1 raeburn 1756: my (%current,%added);
1.45.2.3 raeburn 1757: if (open(PIPE,"firewall-cmd --permanent --zone=$zone --list-services |")) {
1.45.2.1 raeburn 1758: my $svc = <PIPE>;
1759: close(PIPE);
1760: chomp($svc);
1761: map { $current{$_} = 1; } (split(/\s+/,$svc));
1762: }
1763: foreach my $service ('http','https') {
1764: unless ($current{$service}) {
1.45.2.3 raeburn 1765: if (open(PIPE,"firewall-cmd --permanent --zone=$zone --add-service=$service |")) {
1.45.2.1 raeburn 1766: my $result = <PIPE>;
1767: if ($result =~ /^success/) {
1768: $added{$service} = 1;
1769: }
1770: }
1771: }
1772: }
1773: if (keys(%added) > 0) {
1774: print &mt('Firewall configured to allow access for: [_1].',
1775: join(', ',sort(keys(%added))))."\n";
1.45.2.13 raeburn 1776: system('firewall-cmd --reload');
1.45.2.1 raeburn 1777: }
1778: if ($current{'http'} || $current{'https'}) {
1779: print &mt('Firewall already configured to allow access for:[_1].',
1780: (($current{'http'})? ' http':'').(($current{'https'})? ' https':''))."\n";
1781: }
1782: unless ($current{'ssh'}) {
1.45.2.13 raeburn 1783: print &mt('If you would like to allow access to ssh from outside, use the commands:')."\n".
1784: "firewall-cmd --permanent --zone=$zone --add-service=ssh\n".
1785: "firewall-cmd --reload\n";
1.45.2.1 raeburn 1786: }
1787: } elsif ($distro =~ /^(suse|sles)/) {
1.5 raeburn 1788: print &mt('Use [_1] to configure the firewall to allow access for [_2].',
1789: 'yast -- Security and Users -> Firewall -> Interfaces',
1.45.2.1 raeburn 1790: 'ssh, http, https')."\n";
1.5 raeburn 1791: } elsif ($distro =~ /^(debian|ubuntu)(\d+)/) {
1792: if (($1 eq 'ubuntu') || ($2 > 5)) {
1793: print &mt('Use [_1] to configure the firewall to allow access for [_2].',
1794: 'ufw','ssh, http, https')."\n";
1795: } else {
1796: my $fwadded = &get_iptables_rules($distro,$instdir,$apachefw);
1797: if ($fwadded) {
1798: print &mt('Enable firewall? ~[Y/n~]');
1799: my $enable_iptables = &get_user_selection(1);
1800: if ($enable_iptables) {
1801: system('/etc/network/if-pre-up.d/iptables');
1802: print &mt('Firewall enabled using rules defined in [_1].',
1803: '/etc/iptables.loncapa.rules');
1804: }
1805: }
1806: }
1.45.2.3 raeburn 1807: } elsif ($distro =~ /^(scientific|oracle)/) {
1.11 raeburn 1808: print &mt('Use [_1] to configure the firewall to allow access for [_2].',
1809: 'system-config-firewall-tui -- Customize',
1810: 'ssh, http')."\n";
1.1 raeburn 1811: } else {
1.45.2.3 raeburn 1812: my $version;
1813: if ($distro =~ /^(redhat|centos)(\d+)$/) {
1814: $version = $1;
1815: }
1816: if ($version > 5) {
1817: print &mt('Use [_1] to configure the firewall to allow access for [_2].',
1818: 'system-config-firewall-tui -- Customize',
1819: 'ssh, http')."\n";
1820: } else {
1821: print &mt('Use [_1] to configure the firewall to allow access for [_2].',
1822: 'setup -- Firewall configuration -> Customize',
1823: 'ssh, http, https')."\n";
1824: }
1.1 raeburn 1825: }
1826: } else {
1.5 raeburn 1827: &print_and_log(&mt('Skipping Firewall configuration.')."\n");
1.1 raeburn 1828: }
1829:
1830: if ($callsub{'stopsrvcs'}) {
1.45 raeburn 1831: &kill_extra_services($distro,$recommended->{'stopsrvcs'},$uses_systemctl);
1.1 raeburn 1832: } else {
1.10 raeburn 1833: &print_and_log(&mt('Skipping stopping unnecessary service ([_1] daemons).',"'cups','memcached'")."\n");
1.1 raeburn 1834: }
1835:
1836: my ($have_tarball,$updateshown);
1837: if ($callsub{'download'}) {
1838: ($have_tarball,$updateshown) = &download_loncapa($instdir,$sourcetarball);
1839: } else {
1840: print_and_log(&mt('Skipping download of LON-CAPA tar file.')."\n\n");
1841: print &mt('LON-CAPA is available for download from: [_1]',
1842: 'http://install.loncapa.org/')."\n";
1843: if (!-e '/etc/loncapa-release') {
1844: &print_and_log(&mt('LON-CAPA is not yet installed on your system.').
1845: "\n\n".
1846: &mt('You may retrieve the source for LON-CAPA by executing:')."\n".
1847: "wget http://install.loncapa.org/versions/$lctarball\n");
1848: } else {
1849: my $currentversion;
1850: if (open(my $fh,"</etc/loncapa-release")) {
1851: my $version = <$fh>;
1852: chomp($version);
1853: if ($version =~ /^\QLON-CAPA release \E([\w\-.]+)$/) {
1854: $currentversion = $1;
1855: }
1856: }
1857: if ($currentversion ne '') {
1858: print &mt('Version of LON-CAPA currently installed on this server is: [_1].',
1859: $currentversion),"\n";
1860: if ($production) {
1861: print &mt('The latest production release of LON-CAPA is [_1].',$production)."\n";
1862: }
1863: if ($testing) {
1864: print &mt('The latest testing release of LON-CAPA is [_1].',$testing)."\n";
1865: }
1866: }
1867: }
1868: if ($filetouse ne '') {
1869: $have_tarball = 1;
1870: }
1871: }
1872:
1873: print "\n".&mt('Requested configuration complete.')."\n\n";
1874: if ($have_tarball && !$updateshown) {
1875: my ($lcdir) = ($sourcetarball =~ /^([\w.\-]+)\.tar.gz$/);
1.45.2.16 raeburn 1876: if ($lcdir eq 'loncapa-current') {
1877: $lcdir = "loncapa-X.Y.Z (X.Y.Z should correspond to a version number like '2.11.3')";
1878: }
1.45.2.14 raeburn 1879: my ($apachename,$lc_uses_systemctl,$uses_sudo);
1.45.2.12 raeburn 1880: if ($distro =~ /^(suse|sles|debian|ubuntu)([\d.]+)/) {
1881: if (($1 eq 'suse') && ($2 < 10)) {
1882: $apachename = 'apache';
1883: } else {
1884: $apachename = 'apache2';
1885: }
1886: } else {
1887: $apachename = 'httpd';
1888: }
1889: if ($distro =~ /^oracle(\d+)$/) {
1890: if ($1 > 6) {
1891: $lc_uses_systemctl = 1;
1892: }
1893: } elsif ($distro =~ /^(?:rhes|centos)(\d+)$/) {
1894: if ($1 > 7) {
1895: $lc_uses_systemctl = 1;
1896: }
1897: } elsif ($distro =~ /^ubuntu(\d+)$/) {
1898: if ($1 > 16) {
1899: $lc_uses_systemctl = 1;
1900: }
1901: $uses_sudo = 1;
1902: } elsif ($distro =~ /^sles(\d+)$/) {
1903: if ($1 > 12) {
1904: $lc_uses_systemctl = 1;
1905: }
1906: }
1.1 raeburn 1907: if (!-e '/etc/loncapa-release') {
1908: print &mt('If you are now ready to install LON-CAPA, enter the following commands:')."\n\n";
1909: } else {
1.45.2.12 raeburn 1910: my $lcstop = '/etc/init.d/loncontrol stop';
1911: if ($lc_uses_systemctl) {
1912: $lcstop = 'systemctl stop loncontrol';
1913: }
1914: my $apachestop = "/etc/init.d/$apachename stop";
1915: if ($uses_systemctl) {
1916: $apachestop = "systemctl stop $apachename";
1917: }
1918: if ($uses_sudo) {
1.45.2.16 raeburn 1919: $lcstop = 'sudo '.$lcstop;
1.45.2.12 raeburn 1920: $apachestop = 'sudo '.$apachestop;
1.1 raeburn 1921: }
1.45.2.12 raeburn 1922: print &mt('If you are now ready to update LON-CAPA, enter the following commands:').
1923: "\n\n$lcstop\n$apachestop\n";
1.1 raeburn 1924: }
1.45.2.16 raeburn 1925: my ($extract,$update);
1926: my $homedir = '/root';
1927: if ($uses_sudo) {
1928: $extract = 'sudo ';
1929: $update = 'sudo ';
1930: if ($instdir ne $homedir) {
1931: ($homedir) = ($instdir =~ m{^(.*)/[^/]+$});
1932: }
1933: }
1934: $extract .= "tar zxf $sourcetarball --directory $homedir";
1935: $update .= './UPDATE';
1936: print "$extract\n".
1937: "cd $homedir/$lcdir\n".
1938: "$update\n";
1.1 raeburn 1939: if (-e '/etc/loncapa-release') {
1.45.2.12 raeburn 1940: my $lcstart = '/etc/init.d/loncontrol start';
1941: if ($lc_uses_systemctl) {
1942: $lcstart = '/home/httpd/perl/loncontrol start';
1943: }
1944: my $apachestart = "/etc/init.d/$apachename start";
1945: if ($uses_systemctl) {
1946: $apachestart = "systemctl start $apachename";
1947: }
1948: if ($uses_sudo) {
1949: $lcstart = 'sudo '.$lcstart;
1950: $apachestart = 'sudo '.$apachestart;
1951: }
1952: print "$lcstart\n";
1953: print "$apachestart\n";
1.1 raeburn 1954: }
1955: }
1956: exit;
1957:
1958: #
1959: # End main script
1960: #
1961:
1962: #
1963: # Routines for the actions
1964: #
1965:
1966: sub setup_www {
1967: ##
1968: ## Set up www
1969: ##
1970: print_and_log(&mt('Creating user [_1]',"'www'")."\n");
1971: # -- Add group
1972:
1973: my $status = `/usr/sbin/groupadd www`;
1974: if ($status =~ /\QGroup `www' already exists.\E/) {
1975: print &mt('Group [_1] already exists.',"'www'")."\n";
1976: } elsif ($status ne '') {
1977: print &mt('Unable to add group [_1].',"'www'")."\n";
1978: }
1979:
1980: my $gid = getgrnam('www');
1981:
1982: if (open (PIPE, "/usr/sbin/useradd -c LONCAPA -g $gid www 2>&1 |")) {
1983: $status = <PIPE>;
1984: close(PIPE);
1985: chomp($status);
1986: if ($status =~ /\QAccount `www' already exists.\E/) {
1987: print &mt('Account [_1] already exists.',"'www'")."\n";
1988: } elsif ($status ne '') {
1989: print &mt('Unable to add user [_1].',"'www'")."\n";
1990: }
1991: } else {
1992: print &mt('Unable to run command to add user [_1].',"'www'")."\n";
1993: }
1994:
1995: my $uid = &uid_of_www();
1996: if (($gid ne '') && ($uid ne '')) {
1997: if (!-e '/home/www') {
1998: mkdir('/home/www',0755);
1999: system('chown www:www /home/www');
2000: }
2001: }
2002: writelog ($status);
2003: }
2004:
2005: sub uid_of_www {
2006: my ($num) = (getpwnam('www'))[2];
2007: return $num;
2008: }
2009:
2010: sub build_and_install_mod_auth_external {
2011: my ($instdir) = @_;
2012: my $num = &uid_of_www();
2013: # Patch pwauth
2014: print_and_log(&mt('Building authentication system for LON-CAPA users.')."\n");
2015: my $patch = <<"ENDPATCH";
2016: 148c148
2017: < #define SERVER_UIDS 99 /* user "nobody" */
2018: ---
2019: > #define SERVER_UIDS $num /* user "www" */
2020: ENDPATCH
2021:
2022: if (! -e "/usr/bin/patch") {
2023: print_and_log(&mt('You must install the software development tools package: [_1], when installing Linux.',"'patch'")."\n");
2024: print_and_log(&mt('Authentication installation not completed.')."\n");
2025: return;
2026: }
2027: if (&skip_if_nonempty(`cd /tmp; tar zxf $instdir/pwauth-2.2.8.tar.gz`,
2028: &mt('Unable to extract pwauth')."\n")) {
2029: return;
2030: }
2031: my $dir = "/tmp/pwauth-2.2.8";
2032: if (open(PATCH,"| patch $dir/config.h")) {
2033: print PATCH $patch;
2034: close(PATCH);
2035: print_and_log("\n");
2036: ##
2037: ## Compile patched pwauth
2038: ##
2039: print_and_log(&mt('Compiling pwauth')."\n");
1.12 raeburn 2040: my $result = `cd $dir/; make 2>/dev/null `;
1.1 raeburn 2041: my $expected = <<"END";
2042: gcc -g -c -o pwauth.o pwauth.c
2043: gcc -o pwauth -g pwauth.o -lcrypt
2044: END
2045: if ($result eq $expected) {
2046: print_and_log(&mt('Apparent success compiling pwauth:').
2047: "\n".$result );
2048: # Install patched pwauth
2049: print_and_log(&mt('Copying pwauth to [_1]',' /usr/local/sbin')."\n");
2050: if (copy "$dir/pwauth","/usr/local/sbin/pwauth") {
1.5 raeburn 2051: if (chmod(06755, "/usr/local/sbin/pwauth")) {
1.1 raeburn 2052: print_and_log(&mt('[_1] copied successfully',"'pwauth'").
2053: "\n");
2054: } else {
2055: print &mt('Unable to set permissions on [_1].'.
2056: "/usr/local/sbin/pwauth")."\n";
2057: }
2058: } else {
2059: print &mt('Unable to copy [_1] to [_2]',
2060: "'$dir/pwauth'","/usr/local/sbin/pwauth")."\n$!\n";
2061: }
2062: } else {
2063: print &mt('Unable to compile patched [_1].'."'pwauth'")."\n";
2064: }
2065: } else {
2066: print &mt('Unable to start patch for [_1]',"'pwauth'")."\n";
2067: }
2068: print_and_log("\n");
2069: }
2070:
2071: sub kill_extra_services {
1.45 raeburn 2072: my ($distro,$stopsrvcs,$uses_systemctl) = @_;
1.1 raeburn 2073: if (ref($stopsrvcs) eq 'HASH') {
2074: my @stopping = sort(keys(%{$stopsrvcs}));
2075: if (@stopping) {
1.6 raeburn 2076: my $kill_list = join("', '",@stopping);
1.1 raeburn 2077: if ($kill_list) {
2078: $kill_list = "'".$kill_list."'";
1.6 raeburn 2079: &print_and_log("\n".&mt('Killing unnecessary services ([_1] daemon(s)).',$kill_list)."\n");
2080: foreach my $service (@stopping) {
2081: my $daemon = $service;
2082: if ($service eq 'cups') {
2083: $daemon = 'cupsd';
2084: if ($distro =~ /^(?:debian|ubuntu)(\d+)/) {
2085: my $version = $1;
2086: if (($distro =~ /^ubuntu/) && ($version <= 8)) {
2087: $daemon = 'cupsys';
2088: }
1.12 raeburn 2089: } else {
1.8 raeburn 2090: $daemon = 'cups';
1.6 raeburn 2091: }
2092: }
1.12 raeburn 2093: my $cmd = "ps -ef |grep '$daemon' |grep -v grep";
2094: if (open(PIPE,'-|',$cmd)) {
2095: my $daemonrunning = <PIPE>;
2096: chomp($daemonrunning);
2097: close(PIPE);
2098: if ($daemonrunning) {
2099: &print_and_log(`/etc/init.d/$daemon stop`);
2100: }
2101: }
1.1 raeburn 2102: &print_and_log(&mt('Removing [_1] from startup.',$service)."\n");
1.45 raeburn 2103: if ($distro =~ /^(?:debian|ubuntu)(\d+)/) {
2104: my $version = $1;
2105: if (($distro =~ /^ubuntu/) && ($version > 16)) {
2106: if (ref($uses_systemctl) eq 'HASH') {
2107: if ($uses_systemctl->{$service}) {
2108: if (`systemctl is-enabled $service`) {
2109: &print_and_log(`systemctl disable $service`);
2110: }
2111: }
2112: }
2113: } else {
2114: &print_and_log(`update-rc.d -f $daemon remove`);
2115: }
1.1 raeburn 2116: } else {
1.35 raeburn 2117: if (ref($uses_systemctl) eq 'HASH') {
2118: if ($uses_systemctl->{$service}) {
2119: if (`systemctl is-enabled $service`) {
2120: &print_and_log(`systemctl disable $service`);
2121: }
2122: } else {
2123: &print_and_log(`/sbin/chkconfig --del $service`);
2124: }
2125: } else {
2126: &print_and_log(`/sbin/chkconfig --del $service`);
2127: }
1.1 raeburn 2128: }
2129: }
2130: }
2131: }
2132: }
2133: return;
2134: }
2135:
2136: sub setup_mysql {
1.45.2.15 raeburn 2137: my ($setup_mysql_permissions,$dbh,$has_pass,$mysql_unix_socket,$has_lcdb,$distro) = @_;
1.4 raeburn 2138: my @mysql_lc_commands;
1.1 raeburn 2139: unless ($has_lcdb) {
1.45.2.15 raeburn 2140: my $createcmd = 'CREATE DATABASE loncapa';
2141: if ($distro =~ /^sles(\d+)/) {
2142: if ($1 > 11) {
2143: $createcmd .= ' CHARACTER SET utf8 COLLATE utf8_general_ci';
2144: }
2145: } elsif ($distro =~ /^ubuntu(\d+)/) {
2146: if ($1 > 16) {
2147: $createcmd .= ' CHARACTER SET latin1 COLLATE latin1_swedish_ci';
2148: }
2149: }
2150: push(@mysql_lc_commands,$createcmd);
1.1 raeburn 2151: }
1.4 raeburn 2152: push(@mysql_lc_commands,"USE loncapa");
2153: push(@mysql_lc_commands,qq{
1.18 raeburn 2154: CREATE TABLE IF NOT EXISTS metadata (title TEXT, author TEXT, subject TEXT, url TEXT, keywords TEXT, version TEXT, notes TEXT, abstract TEXT, mime TEXT, language TEXT, creationdate DATETIME, lastrevisiondate DATETIME, owner TEXT, copyright TEXT, domain TEXT, dependencies TEXT, modifyinguser TEXT, authorspace TEXT, lowestgradelevel TEXT, highestgradelevel TEXT, standards TEXT, count INT, course INT, course_list TEXT, goto INT, goto_list TEXT, comefrom INT, comefrom_list TEXT, sequsage INT, sequsage_list TEXT, stdno INT, stdno_list TEXT, avetries FLOAT, avetries_list TEXT, difficulty FLOAT, difficulty_list TEXT, disc FLOAT, disc_list TEXT, clear FLOAT, technical FLOAT, correct FLOAT, helpful FLOAT, depth FLOAT, hostname TEXT, FULLTEXT idx_title (title), FULLTEXT idx_author (author), FULLTEXT idx_subject (subject), FULLTEXT idx_url (url), FULLTEXT idx_keywords (keywords), FULLTEXT idx_version (version), FULLTEXT idx_notes (notes), FULLTEXT idx_abstract (abstract), FULLTEXT idx_mime (mime), FULLTEXT idx_language (language), FULLTEXT idx_owner (owner), FULLTEXT idx_copyright (copyright)) ENGINE=MYISAM
1.4 raeburn 2155: });
1.1 raeburn 2156: if ($setup_mysql_permissions) {
1.45.2.9 raeburn 2157: &setup_mysql_permissions($dbh,$has_pass,$mysql_unix_socket,@mysql_lc_commands);
1.1 raeburn 2158: } else {
2159: print_and_log(&mt('Skipping MySQL permissions setup.')."\n");
2160: if ($dbh) {
1.4 raeburn 2161: if (@mysql_lc_commands) {
2162: foreach my $lccmd (@mysql_lc_commands) {
2163: $dbh->do($lccmd) || print $dbh->errstr."\n";
2164: }
2165: }
1.1 raeburn 2166: print_and_log(&mt('MySQL database set up complete.')."\n");
2167: } else {
2168: print_and_log(&mt('Problem accessing MySQL.')."\n");
2169: }
2170: }
2171: }
2172:
2173: sub setup_mysql_permissions {
1.45.2.9 raeburn 2174: my ($dbh,$has_pass,$mysql_unix_socket,@mysql_lc_commands) = @_;
1.38 raeburn 2175: my ($mysqlversion,$mysqlsubver,$mysqlname) = &get_mysql_version();
1.45.2.9 raeburn 2176: my ($usescreate,$usesauth,$is_mariadb,$hasauthcol,@mysql_commands);
1.38 raeburn 2177: if ($mysqlname =~ /^MariaDB/i) {
1.45.2.2 raeburn 2178: $is_mariadb = 1;
1.45.2.9 raeburn 2179: if ($mysqlversion >= 10.4) {
2180: $usescreate = 1;
2181: } elsif ($mysqlversion >= 10.2) {
1.38 raeburn 2182: $usesauth = 1;
1.42 raeburn 2183: } elsif ($mysqlversion >= 5.5) {
2184: $hasauthcol = 1;
1.38 raeburn 2185: }
2186: } else {
2187: if (($mysqlversion > 5.7) || (($mysqlversion == 5.7) && ($mysqlsubver > 5))) {
2188: $usesauth = 1;
1.42 raeburn 2189: } elsif (($mysqlversion >= 5.6) || (($mysqlversion == 5.5) && ($mysqlsubver >= 7))) {
2190: $hasauthcol = 1;
1.38 raeburn 2191: }
2192: }
1.45.2.9 raeburn 2193: if ($usescreate) {
2194: @mysql_commands = ("CREATE USER 'www'\@'localhost' IDENTIFIED BY 'localhostkey'");
2195: } elsif ($usesauth) {
1.45.2.15 raeburn 2196: @mysql_commands = ("INSERT user (Host, User, ssl_cipher, x509_issuer, x509_subject, authentication_string) VALUES('localhost','www','','','','')",
2197: "FLUSH PRIVILEGES");
1.45.2.2 raeburn 2198: if ($is_mariadb) {
2199: push(@mysql_commands,"ALTER USER 'www'\@'localhost' IDENTIFIED BY 'localhostkey'");
2200: } else {
2201: push(@mysql_commands,"ALTER USER 'www'\@'localhost' IDENTIFIED WITH mysql_native_password BY 'localhostkey'");
2202: }
1.42 raeburn 2203: } elsif ($hasauthcol) {
2204: @mysql_commands = ("INSERT user (Host, User, Password, ssl_cipher, x509_issuer, x509_subject, authentication_string) VALUES('localhost','www',password('localhostkey'),'','','','');");
1.36 raeburn 2205: } else {
1.42 raeburn 2206: @mysql_commands = ("INSERT user (Host, User, Password, ssl_cipher, x509_issuer, x509_subject) VALUES('localhost','www',password('localhostkey'),'','','');");
1.36 raeburn 2207: }
1.1 raeburn 2208: if ($mysqlversion < 4) {
1.4 raeburn 2209: push (@mysql_commands,"
2210: INSERT db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv) VALUES('localhost','loncapa','www','Y','Y','Y','Y','Y','Y','N','Y','Y','Y')");
2211: } else {
2212: push (@mysql_commands,"
2213: INSERT db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Create_tmp_table_priv,Lock_tables_priv) VALUES('localhost','loncapa','www','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y')");
1.1 raeburn 2214: }
1.4 raeburn 2215: push(@mysql_commands,"DELETE FROM user WHERE host<>'localhost'");
1.45.2.9 raeburn 2216: if (($has_pass) || ($mysql_unix_socket)) {
1.1 raeburn 2217: if ($dbh) {
1.4 raeburn 2218: push(@mysql_commands,"FLUSH PRIVILEGES");
2219: if (@mysql_commands) {
2220: foreach my $cmd (@mysql_commands) {
2221: $dbh->do($cmd) || print $dbh->errstr."\n";
2222: }
2223: }
2224: if (@mysql_lc_commands) {
2225: foreach my $lccmd (@mysql_lc_commands) {
2226: $dbh->do($lccmd) || print $dbh->errstr."\n";
2227: }
2228: }
1.1 raeburn 2229: print_and_log(&mt('Permissions set for LON-CAPA MySQL user: [_1]',"'www'")."\n");
2230: } else {
2231: print_and_log(&mt('Problem accessing MySQL.')."\n".
2232: &mt('Permissions not set.')."\n");
2233: }
2234: } else {
2235: my ($firstpass,$secondpass,$got_passwd,$newmysqlpass);
2236: print &mt('Please enter a root password for the mysql database.')."\n".
2237: &mt('It does not have to match your root account password, but you will need to remember it.')."\n";
2238: my $maxtries = 10;
2239: my $trial = 0;
2240: while ((!$got_passwd) && ($trial < $maxtries)) {
2241: $firstpass = &get_mysql_password(&mt('Enter password'));
2242: if (length($firstpass) > 5) {
2243: $secondpass = &get_mysql_password(&mt('Enter password a second time'));
2244: if ($firstpass eq $secondpass) {
2245: $got_passwd = 1;
2246: $newmysqlpass = $firstpass;
2247: } else {
2248: print(&mt('Passwords did not match. Please try again.')."\n");
2249: }
2250: $trial ++;
2251: } else {
2252: print(&mt('Password too short.')."\n".
2253: &mt('Please choose a password with at least six characters.')."\n");
2254: }
2255: }
2256: if ($got_passwd) {
1.45.2.2 raeburn 2257: my (@newpass_cmds) = &new_mysql_rootpasswd($newmysqlpass,$usesauth,$is_mariadb);
1.4 raeburn 2258: push(@mysql_commands,@newpass_cmds);
1.1 raeburn 2259: } else {
2260: print_and_log(&mt('Failed to get MySQL root password from user input.')."\n");
2261: }
2262: if ($dbh) {
1.4 raeburn 2263: if (@mysql_commands) {
2264: foreach my $cmd (@mysql_commands) {
2265: $dbh->do($cmd) || print $dbh->errstr."\n";
2266: }
2267: }
2268: if (@mysql_lc_commands) {
2269: foreach my $lccmd (@mysql_lc_commands) {
2270: $dbh->do($lccmd) || print $dbh->errstr."\n";
2271: }
2272: }
1.1 raeburn 2273: if ($got_passwd) {
2274: print_and_log(&mt('MySQL root password stored.')."\n".
2275: &mt('Permissions set for LON-CAPA MySQL user: [_1].',"'www'")."\n");
2276: } else {
2277: print_and_log(&mt('Permissions set for LON-CAPA MySQL user: [_1].',"'www'")."\n");
2278: }
2279: } else {
2280: print_and_log(&mt('Problem accessing MySQL.')."\n".
2281: &mt('Permissions not set.')."\n");
2282: }
2283: }
2284: }
2285:
2286: sub new_mysql_rootpasswd {
1.45.2.2 raeburn 2287: my ($currmysqlpass,$usesauth,$is_mariadb) = @_;
1.36 raeburn 2288: if ($usesauth) {
1.45.2.2 raeburn 2289: if ($is_mariadb) {
2290: return ("ALTER USER 'root'\@'localhost' IDENTIFIED BY '$currmysqlpass'",
2291: "FLUSH PRIVILEGES;");
2292: } else {
2293: return ("ALTER USER 'root'\@'localhost' IDENTIFIED WITH mysql_native_password BY '$currmysqlpass'",
2294: "FLUSH PRIVILEGES;");
2295: }
1.36 raeburn 2296: } else {
2297: return ("SET PASSWORD FOR 'root'\@'localhost'=PASSWORD('$currmysqlpass')",
2298: "FLUSH PRIVILEGES;");
2299: }
1.1 raeburn 2300: }
2301:
2302: sub get_mysql_version {
1.38 raeburn 2303: my ($version,$subversion,$name);
1.1 raeburn 2304: if (open(PIPE," mysql -V |")) {
2305: my $info = <PIPE>;
2306: chomp($info);
2307: close(PIPE);
1.45.2.7 raeburn 2308: ($version,$subversion,$name) = ($info =~ /(\d+\.\d+)\.(\d+)(?:\-?(\w*),|)/);
1.1 raeburn 2309: } else {
2310: print &mt('Could not determine which version of MySQL is installed.').
2311: "\n";
2312: }
1.38 raeburn 2313: return ($version,$subversion,$name);
1.1 raeburn 2314: }
2315:
2316: ###########################################################
2317: ##
2318: ## RHEL/CentOS/Fedora/Scientific Linux
2319: ## Copy LON-CAPA httpd.conf to /etc/httpd/conf
2320: ##
2321: ###########################################################
2322:
2323: sub copy_httpd_conf {
1.14 raeburn 2324: my ($instdir,$distro) = @_;
2325: my $configfile = 'httpd.conf';
1.45.2.3 raeburn 2326: if ($distro =~ /^(?:centos|rhes|scientific|oracle)(\d+)$/) {
1.29 raeburn 2327: if ($1 >= 7) {
2328: $configfile = 'apache2.4/httpd.conf';
2329: } elsif ($1 > 5) {
1.14 raeburn 2330: $configfile = 'new/httpd.conf';
2331: }
2332: } elsif ($distro =~ /^fedora(\d+)$/) {
1.29 raeburn 2333: if ($1 > 17) {
2334: $configfile = 'apache2.4/httpd.conf';
2335: } elsif ($1 > 10) {
1.14 raeburn 2336: $configfile = 'new/httpd.conf';
2337: }
2338: }
1.1 raeburn 2339: print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',"'httpd.conf'",
2340: "'/etc/httpd/conf/httpd.conf'")."\n");
2341: copy "/etc/httpd/conf/httpd.conf","/etc/httpd/conf/httpd.conf.original";
1.14 raeburn 2342: copy "$instdir/centos-rhes-fedora-sl/$configfile","/etc/httpd/conf/httpd.conf";
1.5 raeburn 2343: chmod(0444,"/etc/httpd/conf/httpd.conf");
1.1 raeburn 2344: print_and_log("\n");
2345: }
2346:
1.45.2.5 raeburn 2347: ###########################################################
2348: ##
2349: ## RHEL/CentOS/Fedora/Scientific Linux
2350: ## Copy LON-CAPA mpm.conf to /etc/httpd/conf.modules.d/00-mpm.conf
2351: ##
2352: ## The LON-CAPA mpm.conf enables the prefork MPM module in
2353: ## Apache. This is also the default for RHEL/CentOS/Oracle
2354: ## Linux 7 and earlier, and Fedora 26 and earlier. For more
2355: ## recent versions of those distros, the event MPM is enabled
2356: ## by default. After ©_mpm_conf() is run, the prefork MPM
2357: ## module will be enabled instead of the event MPM module.
2358: ##
2359: ###########################################################
2360:
2361: sub copy_mpm_conf {
2362: my ($instdir,$distro) = @_;
2363: my $mpmfile = 'mpm.conf';
2364: if ((-e "/etc/httpd/conf.modules.d/00-mpm.conf") &&
2365: (-e "$instdir/centos-rhes-fedora-sl/$mpmfile")) {
2366: print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',"'mpm.conf'",
2367: "'/etc/httpd/conf.modules.d/00-mpm.conf'")."\n");
2368: copy "$instdir/centos-rhes-fedora-sl/$mpmfile","/etc/httpd/conf.modules.d/00-mpm.conf";
2369: chmod(0644,"/etc/httpd/conf.modules.d/00-mpm.conf");
2370: print_and_log("\n");
2371: } else {
2372: my $logfail;
2373: if ($distro =~ /^(?:centos|rhes|scientific|oracle)(\d+)$/) {
2374: if ($1 > 7) {
2375: $logfail = 1;
2376: }
2377: } elsif ($distro =~ /^fedora(\d+)$/) {
2378: if ($1 > 26) {
2379: $logfail = 1;
2380: }
2381: }
2382: if ($logfail) {
2383: print_and_log(&mt('Warning: copying the LON-CAPA [_1] failed because [_2] and/or [_3] are missing.',
2384: $mpmfile,"'$instdir/centos-rhes-fedora-sl/$mpmfile'",
2385: "'/etc/httpd/conf.modules.d/00-mpm.conf'"));
2386: print_and_log("\n");
2387: }
2388: }
2389: }
2390:
1.1 raeburn 2391: #########################################################
2392: ##
1.17 raeburn 2393: ## Ubuntu/Debian -- copy our loncapa configuration file to
1.1 raeburn 2394: ## sites-available and set the symlink from sites-enabled.
2395: ##
2396: #########################################################
2397:
2398: sub copy_apache2_debconf {
1.28 raeburn 2399: my ($instdir,$distro) = @_;
1.6 raeburn 2400: my $apache2_mods_enabled_dir = '/etc/apache2/mods-enabled';
2401: my $apache2_mods_available_dir = '/etc/apache2/mods-available';
2402: foreach my $module ('headers.load','expires.load') {
2403: unless (-l "$apache2_mods_enabled_dir/$module") {
2404: symlink("$apache2_mods_available_dir/$module","$apache2_mods_enabled_dir/$module");
2405: print_and_log(&mt('Enabling "[_1]" Apache module.',$module)."\n");
2406: }
2407: }
1.28 raeburn 2408: my $apache2_sites_enabled_dir = '/etc/apache2/sites-enabled';
2409: my $apache2_sites_available_dir = '/etc/apache2/sites-available';
2410: my $defaultconfig = "$apache2_sites_enabled_dir/000-default";
1.45.2.10 raeburn 2411: my $defaultsite = "$apache2_sites_enabled_dir/loncapa.conf";
1.28 raeburn 2412: my ($distname,$version);
2413: if ($distro =~ /^(debian|ubuntu)(\d+)$/) {
2414: $distname = $1;
2415: $version = $2;
2416: }
2417: if (($distname eq 'ubuntu') && ($version > 12)) {
2418: $defaultconfig = "$apache2_sites_enabled_dir/000-default.conf";
2419: }
1.45.2.7 raeburn 2420: my ($skipconf,$skipsite,$skipstatus);
1.28 raeburn 2421: if (($distname eq 'ubuntu') && ($version > 12)) {
2422: my $apache2_conf_enabled_dir = '/etc/apache2/conf-enabled';
2423: my $apache2_conf_available_dir = '/etc/apache2/conf-available';
1.33 raeburn 2424: my $defaultconf = $apache2_conf_enabled_dir.'/loncapa.conf';
1.45.2.7 raeburn 2425: if ((-e "$apache2_conf_available_dir/loncapa") && (-e "$instdir/debian-ubuntu/ubuntu14/loncapa_conf")) {
1.45.2.8 raeburn 2426: if (open(PIPE, "diff --brief $apache2_conf_available_dir/loncapa $instdir/debian-ubuntu/ubuntu14/loncapa_conf |")) {
1.45.2.7 raeburn 2427: my $diffres = <PIPE>;
2428: close(PIPE);
2429: chomp($diffres);
2430: if ($diffres) {
1.45.2.10 raeburn 2431: copy("$apache2_conf_available_dir/loncapa","$apache2_conf_available_dir/loncapa.conf.original");
2432: } else {
2433: copy("$apache2_conf_available_dir/loncapa","$apache2_conf_available_dir/loncapa.conf");
1.45.2.11 raeburn 2434: chdir($apache2_conf_enabled_dir);
2435: symlink('../conf-available/loncapa.conf','loncapa.conf');
2436: chdir($instdir);
1.45.2.7 raeburn 2437: }
2438: if (-l $defaultconf) {
2439: my $linkfname = readlink($defaultconf);
1.45.2.11 raeburn 2440: if ($linkfname ne '') {
2441: $linkfname = Cwd::abs_path(File::Spec->rel2abs($linkfname,$apache2_conf_enabled_dir));
2442: }
1.45.2.7 raeburn 2443: if ($linkfname eq "$apache2_conf_available_dir/loncapa") {
1.45.2.10 raeburn 2444: unlink($defaultconf);
2445: }
2446: }
2447: unlink("$apache2_conf_available_dir/loncapa");
2448: }
2449: }
2450: if ((-e "$apache2_conf_available_dir/loncapa.conf") && (-e "$instdir/debian-ubuntu/ubuntu14/loncapa_conf")) {
2451: if (open(PIPE, "diff --brief $apache2_conf_available_dir/loncapa.conf $instdir/debian-ubuntu/ubuntu14/loncapa_conf |")) {
2452: my $diffres = <PIPE>;
2453: close(PIPE);
2454: chomp($diffres);
2455: if ($diffres) {
2456: copy("$apache2_conf_available_dir/loncapa.conf","$apache2_conf_available_dir/loncapa.conf.original");
2457: }
2458: if (-l $defaultconf) {
2459: my $linkfname = readlink($defaultconf);
1.45.2.11 raeburn 2460: if ($linkfname ne '') {
2461: $linkfname = Cwd::abs_path(File::Spec->rel2abs($linkfname,$apache2_conf_enabled_dir));
2462: }
1.45.2.10 raeburn 2463: if ($linkfname eq "$apache2_conf_available_dir/loncapa.conf") {
1.45.2.7 raeburn 2464: unless ($diffres) {
2465: $skipconf = 1;
2466: }
2467: }
2468: }
2469: }
2470: }
2471: unless ($skipconf) {
2472: print_and_log(&mt('Copying loncapa [_1] config file to [_2] and pointing [_3] to it from conf-enabled.',"'apache2'","'/etc/apache2/conf-available'","'loncapa.conf symlink'")."\n");
1.45.2.10 raeburn 2473: copy("$instdir/debian-ubuntu/ubuntu14/loncapa_conf","$apache2_conf_available_dir/loncapa.conf");
2474: chmod(0444,"$apache2_conf_available_dir/loncapa.conf");
1.45.2.7 raeburn 2475: if (-l $defaultconf) {
2476: unlink($defaultconf);
2477: }
1.45.2.11 raeburn 2478: chdir($apache2_conf_enabled_dir);
2479: symlink('../conf-available/loncapa.conf','loncapa.conf');
2480: chdir($instdir);
1.45.2.7 raeburn 2481: }
2482: my $stdsite = "$instdir/debian-ubuntu/ubuntu14/loncapa_site";
2483: if ((-e $stdsite) && (-e "$apache2_sites_available_dir/loncapa")) {
2484: if (open(PIPE, "diff --brief $stdsite $apache2_sites_available_dir/loncapa |")) {
2485: my $diffres = <PIPE>;
2486: close(PIPE);
2487: chomp($diffres);
2488: if ($diffres) {
1.45.2.10 raeburn 2489: copy("$apache2_sites_available_dir/loncapa","$apache2_sites_available_dir/loncapa.conf.original");
2490: } else {
2491: copy("$apache2_sites_available_dir/loncapa","$apache2_sites_available_dir/loncapa.conf");
1.45.2.7 raeburn 2492: }
2493: if (-l $defaultconfig) {
2494: my $linkfname = readlink($defaultconfig);
1.45.2.11 raeburn 2495: if ($linkfname ne '') {
2496: $linkfname = Cwd::abs_path(File::Spec->rel2abs($linkfname,$apache2_sites_enabled_dir));
2497: }
1.45.2.7 raeburn 2498: if ($linkfname eq "$apache2_sites_available_dir/loncapa") {
1.45.2.10 raeburn 2499: unlink($defaultconfig);
2500: }
2501: }
2502: unlink("$apache2_sites_available_dir/loncapa");
2503: }
2504: }
2505: if ((-e $stdsite) && (-e "$apache2_sites_available_dir/loncapa.conf")) {
2506: if (open(PIPE, "diff --brief $stdsite $apache2_sites_available_dir/loncapa.conf |")) {
2507: my $diffres = <PIPE>;
2508: close(PIPE);
2509: chomp($diffres);
2510: if ($diffres) {
2511: copy("$apache2_sites_available_dir/loncapa.conf","$apache2_sites_available_dir/loncapa.conf.original");
2512: }
2513: if (-l $defaultsite) {
2514: my $linkfname = readlink($defaultsite);
1.45.2.11 raeburn 2515: if ($linkfname ne '') {
2516: $linkfname = Cwd::abs_path(File::Spec->rel2abs($linkfname,$apache2_sites_enabled_dir));
2517: }
2518: if ($linkfname eq "$apache2_sites_available_dir/loncapa.conf") {
1.45.2.7 raeburn 2519: unless ($diffres) {
2520: $skipsite = 1;
2521: }
2522: }
2523: }
2524: }
2525: }
2526: unless ($skipsite) {
1.45.2.10 raeburn 2527: print_and_log(&mt('Copying loncapa [_1] site file to [_2] and pointing [_3] to it from sites-enabled.',"'apache2'","'/etc/apache2/sites-available'","'loncapa.conf symlink'")."\n");
2528: copy("$instdir/debian-ubuntu/ubuntu14/loncapa_site","$apache2_sites_available_dir/loncapa.conf");
2529: chmod(0444,"$apache2_sites_available_dir/loncapa.conf");
1.45.2.11 raeburn 2530: chdir($apache2_sites_enabled_dir);
2531: symlink('../sites-available/loncapa.conf','loncapa.conf');
2532: chdir($instdir);
1.45.2.10 raeburn 2533: }
1.45.2.11 raeburn 2534: if (-l $defaultconfig) {
1.45.2.10 raeburn 2535: my $linkfname = readlink($defaultconfig);
1.45.2.11 raeburn 2536: if ($linkfname ne '') {
2537: $linkfname = Cwd::abs_path(File::Spec->rel2abs($linkfname,$apache2_sites_enabled_dir));
2538: }
2539: if ($linkfname eq "$apache2_sites_available_dir/000-default.conf") {
1.45.2.10 raeburn 2540: unlink($defaultconfig);
2541: }
1.45.2.7 raeburn 2542: }
2543: } else {
2544: if ((-e "$instdir/debian-ubuntu/loncapa") && (-e "$apache2_sites_available_dir/loncapa")) {
2545: if (open(PIPE, "diff --brief $instdir/debian-ubuntu/loncapa $apache2_sites_available_dir/loncapa |")) {
2546: my $diffres = <PIPE>;
2547: close(PIPE);
2548: chomp($diffres);
2549: if ($diffres) {
2550: copy("$apache2_sites_available_dir/loncapa","$apache2_sites_available_dir/loncapa.original");
2551: }
2552: if (-l $defaultconfig) {
2553: my $linkfname = readlink($defaultconfig);
2554: if ($linkfname eq "$apache2_sites_available_dir/loncapa") {
2555: unless ($diffres) {
2556: $skipsite = 1;
2557: }
2558: }
2559: }
2560: }
2561: }
2562: unless ($skipsite) {
2563: if (-l $defaultconfig) {
2564: unlink($defaultconfig);
2565: }
2566: print_and_log(&mt('Copying loncapa [_1] config file to [_2] and pointing [_3] to it from sites-enabled.',"'apache2'","'/etc/apache2/sites-available'","'000-default symlink'")."\n");
2567: if (-e "$instdir/debian-ubuntu/loncapa") {
2568: copy("$instdir/debian-ubuntu/loncapa","$apache2_sites_available_dir/loncapa");
2569: chmod(0444,"$apache2_sites_available_dir/loncapa");
2570: symlink("$apache2_sites_available_dir/loncapa","$apache2_sites_enabled_dir/000-default");
2571: }
2572: }
2573: }
2574: if ($distname eq 'ubuntu') {
2575: my $sitestatus = "$apache2_mods_available_dir/status.conf";
2576: my $stdstatus = "$instdir/debian-ubuntu/status.conf";
2577: if ((-e $sitestatus) && (-e $stdstatus)) {
2578: if (open(PIPE, "diff --brief $stdstatus $sitestatus |")) {
2579: my $diffres = <PIPE>;
2580: close(PIPE);
2581: chomp($diffres);
2582: if ($diffres) {
2583: copy("$apache2_mods_available_dir/status.conf","$apache2_mods_available_dir/status.conf.original");
2584: } else {
2585: $skipstatus = 1;
2586: }
2587: }
2588: }
2589: unless ($skipstatus) {
2590: if (-e $stdstatus) {
2591: print_and_log(&mt('Copying loncapa [_1] file to [_2],',"'status.conf'","'/etc/apache2/mods-available/status.conf'")."\n");
2592: copy($stdstatus,$sitestatus);
2593: chmod(0644,$sitestatus);
2594: }
2595: }
1.28 raeburn 2596: }
1.1 raeburn 2597: print_and_log("\n");
2598: }
2599:
2600: ###########################################################
2601: ##
2602: ## openSuSE/SLES Copy apache2 config files:
2603: ## default-server.conf, uid.conf, /etc/sysconfig/apache2
2604: ## and create symlink from /srv/www/conf to /etc/apache2
2605: ##
2606: ###########################################################
2607:
2608: sub copy_apache2_suseconf {
1.45.2.1 raeburn 2609: my ($instdir,$distro) = @_;
2610: my ($name,$version) = ($distro =~ /^(suse|sles)([\d\.]+)$/);
2611: my $conf_file = "$instdir/sles-suse/default-server.conf";
2612: if (($name eq 'sles') && ($version >= 12)) {
2613: $conf_file = "$instdir/sles-suse/apache2.4/default-server.conf";
2614: }
1.1 raeburn 2615: print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',
2616: "'default-server.conf'",
2617: "'/etc/apache2/default-server.conf'")."\n");
2618: if (!-e "/etc/apache2/default-server.conf.original") {
2619: copy "/etc/apache2/default-server.conf","/etc/apache2/default-server.conf.original";
2620: }
1.45.2.1 raeburn 2621: copy $conf_file,"/etc/apache2/default-server.conf";
1.5 raeburn 2622: chmod(0444,"/etc/apache2/default-server.conf");
1.1 raeburn 2623: # Make symlink for conf directory (included in loncapa_apache.conf)
2624: my $can_symlink = (eval { symlink('/etc/apache2','/srv/www/conf'); }, $@ eq '');
2625: if ($can_symlink) {
2626: &print_and_log(&mt('Symlink created for [_1] to [_2].',
2627: "'/srv/www/conf'","'/etc/apache2'")."\n");
2628: } else {
2629: &print_and_log(&mt('Symlink creation failed for [_1] to [_2]. You will need to perform this action from the command line.',"'/srv/www/conf'","'/etc/apache2'")."\n");
2630: }
2631: ©_apache2_conf_files($instdir);
1.45.2.1 raeburn 2632: ©_sysconfig_apache2_file($instdir,$name,$version);
1.1 raeburn 2633: print_and_log("\n");
2634: }
2635:
2636: ###############################################
2637: ##
2638: ## Modify uid.conf
2639: ##
2640: ###############################################
2641: sub copy_apache2_conf_files {
2642: my ($instdir) = @_;
2643: print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',
2644: "'uid.conf'","'/etc/apache2/uid.conf'")."\n");
2645: if (!-e "/etc/apache2/uid.conf.original") {
2646: copy "/etc/apache2/uid.conf","/etc/apache2/uid.conf.original";
2647: }
1.9 raeburn 2648: copy "$instdir/sles-suse/uid.conf","/etc/apache2/uid.conf";
1.5 raeburn 2649: chmod(0444,"/etc/apache2/uid.conf");
1.1 raeburn 2650: }
2651:
2652: ###############################################
2653: ##
2654: ## Modify /etc/sysconfig/apache2
2655: ##
2656: ###############################################
2657: sub copy_sysconfig_apache2_file {
1.45.2.1 raeburn 2658: my ($instdir,$name,$version) = @_;
1.1 raeburn 2659: print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',"'sysconfig/apache2'","'/etc/sysconfig/apache2'")."\n");
2660: if (!-e "/etc/sysconfig/apache2.original") {
2661: copy "/etc/sysconfig/apache2","/etc/sysconfig/apache2.original";
2662: }
1.45.2.1 raeburn 2663: my $sysconf_file = "$instdir/sles-suse/sysconfig_apache2";
2664: if (($name eq 'sles') && ($version >= 12)) {
2665: $sysconf_file = "$instdir/sles-suse/apache2.4/sysconfig_apache2";
2666: }
2667: copy $sysconf_file,"/etc/sysconfig/apache2";
1.5 raeburn 2668: chmod(0444,"/etc/sysconfig/apache2");
1.1 raeburn 2669: }
2670:
2671: ###############################################
2672: ##
2673: ## Add/Modify /etc/insserv/overrides
2674: ##
2675: ###############################################
2676:
2677: sub update_SuSEfirewall2_setup {
2678: my ($instdir) = @_;
2679: print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',"'SuSEfirewall2_setup'","'/etc/insserv/overrides/SuSEfirewall2_setup'")."\n");
2680: if (!-e "/etc/insserv/overrides/SuSEfirewall2_setup") {
2681: if (!-d "/etc/insserv") {
2682: mkdir("/etc/insserv",0755);
2683: }
2684: if (!-d "/etc/insserv/overrides") {
2685: mkdir("/etc/insserv/overrides",0755);
2686: }
2687: } elsif (!-e "/etc/insserv/overrides/SuSEfirewall2_setup.original") {
2688: copy "/etc/insserv/overrides/SuSEfirewall2_setup","/etc/insserv/overrides/SuSEfirewall2_setup.original"
2689: }
1.9 raeburn 2690: copy "$instdir/sles-suse/SuSEfirewall2_setup","/etc/insserv/overrides/SuSEfirewall2_setup";
1.5 raeburn 2691: chmod(0444,"/etc/insserv/overrides/SuSEfirewall2_setup");
2692: }
2693:
2694: sub get_iptables_rules {
2695: my ($distro,$instdir,$apachefw) = @_;
2696: my (@fwchains,@ports);
2697: if (&firewall_is_active()) {
2698: my $iptables = &get_pathto_iptables();
2699: if ($iptables ne '') {
2700: @fwchains = &get_fw_chains($iptables,$distro);
2701: }
2702: }
2703: if (ref($apachefw) eq 'HASH') {
2704: foreach my $service ('http','https') {
2705: unless ($apachefw->{$service}) {
2706: push (@ports,$service);
2707: }
2708: }
2709: } else {
2710: @ports = ('http','https');
2711: }
2712: if (@ports == 0) {
2713: return;
2714: }
2715: my $ask_to_enable;
2716: if (-e "/etc/iptables.loncapa.rules") {
1.9 raeburn 2717: if (open(PIPE, "diff --brief $instdir/debian-ubuntu/iptables.loncapa.rules /etc/iptables.loncapa.rules |")) {
1.5 raeburn 2718: my $diffres = <PIPE>;
2719: close(PIPE);
2720: chomp($diffres);
2721: if ($diffres) {
2722: print &mt('Warning: [_1] exists but differs from LON-CAPA supplied file.','/etc/iptables.loncapa.rules')."\n";
2723: }
2724: } else {
2725: print &mt('Error: unable to open [_1] to compare contents with LON-CAPA supplied file.','/etc/iptables.loncapa.rules')."\n";
2726: }
2727: } else {
1.9 raeburn 2728: if (-e "$instdir/debian-ubuntu/iptables.loncapa.rules") {
2729: copy "$instdir/debian-ubuntu/iptables.loncapa.rules","/etc/iptables.loncapa.rules";
1.5 raeburn 2730: chmod(0600,"/etc/iptables.loncapa.rules");
2731: }
2732: }
2733: if (-e "/etc/iptables.loncapa.rules") {
2734: if (-e "/etc/network/if-pre-up.d/iptables") {
1.9 raeburn 2735: if (open(PIPE, "diff --brief $instdir/debian-ubuntu/iptables /etc/network/if-pre-up/iptables |")) {
1.5 raeburn 2736: my $diffres = <PIPE>;
2737: close(PIPE);
2738: chomp($diffres);
2739: if ($diffres) {
2740: print &mt('Warning: [_1] exists but differs from LON-CAPA supplied file.','/etc/network/if-pre-up.d/iptables')."\n";
2741: }
2742: } else {
2743: print &mt('Error: unable to open [_1] to compare contents with LON-CAPA supplied file.','/etc/network/if-pre-up.d/iptables')."\n";
2744: }
2745: } else {
1.9 raeburn 2746: copy "$instdir/debian-ubuntu/iptables","/etc/network/if-pre-up.d/iptables";
1.5 raeburn 2747: chmod(0755,"/etc/network/if-pre-up.d/iptables");
2748: print_and_log(&mt('Installed script "[_1]" to add iptables rules to block all ports except 22, 80, and 443 when network is enabled during boot.','/etc/network/if-pre-up.d/iptables'));
2749: $ask_to_enable = 1;
2750: }
2751: }
2752: return $ask_to_enable;
1.1 raeburn 2753: }
2754:
2755: sub download_loncapa {
2756: my ($instdir,$lctarball) = @_;
2757: my ($have_tarball,$updateshown);
2758: if (! -e "$instdir/$lctarball") {
2759: print_and_log(&mt('Retrieving LON-CAPA source files from: [_1]',
2760: 'http://install.loncapa.org')."\n");
2761: system("wget http://install.loncapa.org/versions/$lctarball ".
2762: "2>/dev/null 1>/dev/null");
2763: if (! -e "./$lctarball") {
2764: print &mt('Unable to retrieve LON-CAPA source files from: [_1].',
2765: "http://install.loncapa.org/versions/$lctarball")."\n";
2766: } else {
2767: $have_tarball = 1;
2768: }
2769: print_and_log("\n");
2770: } else {
2771: $have_tarball = 1;
2772: print_and_log("
2773: ------------------------------------------------------------------------
2774:
1.45.2.16 raeburn 2775: ".&mt('You seem to have a version of [_1] in [_2]',$lctarball,$instdir)."\n".
1.1 raeburn 2776: &mt('This copy will be used and a new version will NOT be downloaded.')."\n".
2777: &mt('If you wish, you may download a new version by executing:')."
2778:
1.45.2.16 raeburn 2779: wget http://install.loncapa.org/versions/$lctarball
1.1 raeburn 2780:
2781: ------------------------------------------------------------------------
2782: ");
2783: }
2784:
2785: ##
1.45.2.16 raeburn 2786: ## untar loncapa-X.Y.Z.tar.gz
1.1 raeburn 2787: ##
2788: if ($have_tarball) {
1.45.2.16 raeburn 2789: my $homedir = '/root';
2790: my ($targetdir,$chdircmd,$updatecmd);
2791: if (($distro =~ /^ubuntu/) && ($instdir ne $homedir)) {
2792: ($homedir) = ($instdir =~ m{^(.*)/[^/]+$});
2793: $updatecmd = 'sudo ./UPDATE';
2794: } else {
2795: $updatecmd = './UPDATE';
2796: }
1.1 raeburn 2797: print_and_log(&mt('Extracting LON-CAPA source files')."\n");
1.45.2.16 raeburn 2798: if (-e $homedir) {
2799: writelog(`tar zxf $instdir/$lctarball --directory $homedir`);
2800: $targetdir = $homedir;
2801: } else {
2802: writelog(`tar zxf $instdir/$lctarball`);
2803: $targetdir = $instdir;
2804: }
2805: if ($lctarball =~ /^loncapa\-(\d+\.\d+\.\d+(?:|[^.]+))\.tar\.gz$/) {
2806: $chdircmd = "cd $targetdir/loncapa-".$1;
2807: } else {
2808: $chdircmd = "cd $targetdir/loncapa-X.Y.Z (X.Y.Z should correspond to a version number like '2.11.3')";
2809: }
1.1 raeburn 2810: print_and_log("\n");
2811: print &mt('LON-CAPA source files extracted.')."\n".
1.45.2.16 raeburn 2812: &mt('It remains for you to execute the following commands:').
2813: "\n$chdircmd\n$updatecmd\n".
2814: &mt('If you have any trouble, please see [_1] and [_2]',
2815: 'http://install.loncapa.org/','http://help.loncapa.org/')."\n";
1.1 raeburn 2816: $updateshown = 1;
2817: }
2818: return ($have_tarball,$updateshown);
2819: }
2820:
2821: close LOG;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>