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