Diff for /doc/install/linux/install.pl between versions 1.43 and 1.46

version 1.43, 2018/06/10 00:59:11 version 1.46, 2018/07/11 01:58:41
Line 26 Line 26
 use strict;  use strict;
 use File::Copy;  use File::Copy;
 use Term::ReadKey;  use Term::ReadKey;
   use Sys::Hostname::FQDN();
 use DBI;  use DBI;
 use Cwd();  use Cwd();
 use File::Basename();  use File::Basename();
Line 280  sub get_distro { Line 281  sub get_distro {
     return ($distro,$packagecmd,$updatecmd,$installnow);      return ($distro,$packagecmd,$updatecmd,$installnow);
 }  }
   
   sub get_hostname {
       my $hostname;
       print &mt('Enter the hostname of this server, e.g., loncapa.somewhere.edu'."\n");
       my $choice = <STDIN>;
       chomp($choice);
       $choice =~ s/(^\s+|\s+$)//g;
       if ($choice eq '') {
           print &mt("Hostname you entered was either blank or contanied only white space.\n");
       } elsif ($choice =~ /^[\w\.\-]+$/) {
           $hostname = $choice;
       } else {
           print &mt("Hostname you entered was invalid --  a hostname may only contain letters, numbers, - and .\n");
       }
       while ($hostname eq '') {
           $hostname = &get_hostname();
       }
       print "\n";
       return $hostname;
   }
   
 sub check_prerequisites {  sub check_prerequisites {
     my ($packagecmd,$distro) = @_;      my ($packagecmd,$distro) = @_;
     my $gotprereqs;      my $gotprereqs;
Line 389  sub check_required { Line 410  sub check_required {
         return ($distro,$gotprereqs,$localecmd);          return ($distro,$gotprereqs,$localecmd);
     }      }
     my ($mysqlon,$mysqlsetup,$mysqlrestart,$dbh,$has_pass,$has_lcdb,%recommended,      my ($mysqlon,$mysqlsetup,$mysqlrestart,$dbh,$has_pass,$has_lcdb,%recommended,
         $downloadstatus,$filetouse,$production,$testing,$apachefw,$tostop,$uses_systemctl);          $downloadstatus,$filetouse,$production,$testing,$apachefw,$tostop,
           $uses_systemctl,$hostname);
     my $wwwuid = &uid_of_www();      my $wwwuid = &uid_of_www();
     my $wwwgid = getgrnam('www');      my $wwwgid = getgrnam('www');
     if (($wwwuid eq '') || ($wwwgid eq '')) {      if (($wwwuid eq '') || ($wwwgid eq '')) {
Line 398  sub check_required { Line 420  sub check_required {
     unless( -e "/usr/local/sbin/pwauth") {      unless( -e "/usr/local/sbin/pwauth") {
         $recommended{'pwauth'} = 1;          $recommended{'pwauth'} = 1;
     }      }
       my $hostname = Sys::Hostname::FQDN::fqdn();
       if ($hostname eq '') {
           $hostname =&get_hostname();
       } else {
           print &mt("Hostname detected: $hostname. Is that correct? ~[Y/n~]");
           if (!&get_user_selection(1)) {
               $hostname =&get_hostname();
           }
       }
       print_and_log(&mt('Hostname is [_1]',$hostname)."\n");
     $mysqlon = &check_mysql_running($distro);      $mysqlon = &check_mysql_running($distro);
     if ($mysqlon) {      if ($mysqlon) {
         my $mysql_has_wwwuser = &check_mysql_wwwuser();          my $mysql_has_wwwuser = &check_mysql_wwwuser();
Line 429  sub check_required { Line 461  sub check_required {
     ($recommended{'firewall'},$apachefw) = &chkfirewall($distro);      ($recommended{'firewall'},$apachefw) = &chkfirewall($distro);
     ($recommended{'runlevels'},$tostop,$uses_systemctl) = &chkconfig($distro,$instdir);      ($recommended{'runlevels'},$tostop,$uses_systemctl) = &chkconfig($distro,$instdir);
     $recommended{'apache'} = &chkapache($distro,$instdir);      $recommended{'apache'} = &chkapache($distro,$instdir);
       $recommended{'apachessl'} = &chkapachessl($distro,$instdir,$hostname);
     $recommended{'stopsrvcs'} = &chksrvcs($distro,$tostop);      $recommended{'stopsrvcs'} = &chksrvcs($distro,$tostop);
     ($recommended{'download'},$downloadstatus,$filetouse,$production,$testing)       ($recommended{'download'},$downloadstatus,$filetouse,$production,$testing) 
         = &need_download();          = &need_download();
     return ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,      return ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,
             $mysqlrestart,\%recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus,              $mysqlrestart,\%recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus,
             $filetouse,$production,$testing,$apachefw,$uses_systemctl);              $filetouse,$production,$testing,$apachefw,$uses_systemctl,$hostname);
 }  }
   
 sub check_mysql_running {  sub check_mysql_running {
Line 564  sub chkconfig { Line 597  sub chkconfig {
         my $version = $1;          my $version = $1;
         @runlevels = qw/2 3 4 5/;          @runlevels = qw/2 3 4 5/;
         @norunlevels = qw/0 1 6/;          @norunlevels = qw/0 1 6/;
         $checker_bin = '/usr/sbin/sysv-rc-conf';          if (($distro =~ /^ubuntu/) && ($version <= 16)) {
               $checker_bin = '/usr/sbin/sysv-rc-conf';
           } else {
               $uses_systemctl{'ntp'} = 1;
               $uses_systemctl{'mysql'} = 1;
               $uses_systemctl{'apache'} = 1;
               $uses_systemctl{'memcached'} = 1;
               $uses_systemctl{'cups'} = 1;
           }
         $daemon{'mysql'}  = 'mysql';          $daemon{'mysql'}  = 'mysql';
         $daemon{'apache'} = 'apache2';          $daemon{'apache'} = 'apache2';
         $daemon{'ntp'}    = 'ntp';          $daemon{'ntp'}    = 'ntp';
Line 841  sub chkapache { Line 882  sub chkapache {
     return $fixapache;      return $fixapache;
 }  }
   
   sub chkapachessl {
       my ($distro,$instdir,$hostname) = @_;
       my $fixapachessl = 1;
       my $stdconf = "$instdir/loncapassl.conf";
       if (!-e $stdconf) {
           $fixapachessl = 0;
           print &mt('Warning: No LON-CAPA SSL Apache configuration file found for installation check.')."\n";
       } else {
           my $sslfile; 
           if ($distro =~ /^(debian|ubuntu)(\d+)$/) {
               $sslfile = '/etc/apache2/sites-available/loncapassl.conf';
           } elsif ($distro =~ /(suse|sles)/) {
               $sslfile = '/etc/apache2/vhosts.d/loncapassl.conf';
           } else {
               $sslfile = '/etc/httpd/conf.d/loncapassl.conf';
           }
           if ((-e $sslfile) && (-e $stdconf))  {
               if (open(PIPE, "diff -y -bi --suppress-common-lines $stdconf $sslfile |")) {
                   my $diffres = <PIPE>;
                   close(PIPE);
                   chomp($diffres);
                   if ($diffres =~ /^\QServerName internal-{[[[[Hostname]]]]}\E\s+\|\s+\QServerName internal-\E$hostname$/) {
                       $fixapachessl = 0;
                   }
               }
           }
           unless ($fixapachessl) {
               if ($distro =~ /^(debian|ubuntu)(\d+)$/) {
                   unless ((-l '/etc/apache2/sites-enabled/loncapassl.conf') &&
                           (readlink('/etc/apache2/sites-enabled/loncapassl.conf') eq '/etc/apache2/sites-available/loncapassl.conf')) {
                       print_and_log(&mt("Warning, use: 'sudo a2ensite loncapassl.conf' to activate LON-CAPA SSL Apache config\n"));
                   }
               }
           }
       }
       return $fixapachessl;
   }
   
 sub chksrvcs {  sub chksrvcs {
     my ($distro,$tostop) = @_;      my ($distro,$tostop) = @_;
     my %stopsrvcs;      my %stopsrvcs;
Line 1232  print " Line 1311  print "
 ".&mt('3.')." ".&mt('Set-up the MySQL database.')."  ".&mt('3.')." ".&mt('Set-up the MySQL database.')."
 ".&mt('4.')." ".&mt('Set-up MySQL permissions.')."  ".&mt('4.')." ".&mt('Set-up MySQL permissions.')."
 ".&mt('5.')." ".&mt('Configure Apache web server.')."  ".&mt('5.')." ".&mt('Configure Apache web server.')."
 ".&mt('6.')." ".&mt('Configure start-up of services.')."  ".&mt('6.')." ".&mt('Configure SSL for Apache web server.')."
 ".&mt('7.')." ".&mt('Check firewall settings.')."  ".&mt('7.')." ".&mt('Configure start-up of services.')."
 ".&mt('8.')." ".&mt('Stop services not used by LON-CAPA,')."  ".&mt('8.')." ".&mt('Check firewall settings.')."
   ".&mt('9.')." ".&mt('Stop services not used by LON-CAPA,')."
    ".&mt('i.e., services for a print server: [_1] daemon.',"'cups'")."     ".&mt('i.e., services for a print server: [_1] daemon.',"'cups'")."
 ".&mt('9.')." ".&mt('Download LON-CAPA source code in readiness for installation.')."  ".&mt('10.')." ".&mt('Download LON-CAPA source code in readiness for installation.')."
   
 ".&mt('Typically, you will run this script only once, when you first install LON-CAPA.')."   ".&mt('Typically, you will run this script only once, when you first install LON-CAPA.')." 
   
Line 1266  chomp($instdir); Line 1346  chomp($instdir);
   
 my %callsub;  my %callsub;
 my @actions = ('wwwuser','pwauth','mysql','mysqlperms','apache',  my @actions = ('wwwuser','pwauth','mysql','mysqlperms','apache',
                'runlevels','firewall','stopsrvcs','download');                 'apachessl','runlevels','firewall','stopsrvcs','download');
 my %prompts = &texthash(   my %prompts = &texthash( 
     wwwuser    => "Create the 'www' user?",      wwwuser    => "Create the 'www' user?",
     pwauth     => 'Install the package LON-CAPA uses to authenticate users?',      pwauth     => 'Install the package LON-CAPA uses to authenticate users?',
     mysql      => 'Set-up the MySQL database?',      mysql      => 'Set-up the MySQL database?',
     mysqlperms => 'Set-up MySQL permissions?',      mysqlperms => 'Set-up MySQL permissions?',
     apache     => 'Configure Apache web server?',      apache     => 'Configure Apache web server?',
       apachessl  => 'Configure SSL for Apache web server?', 
     runlevels  => 'Set overrides for start-up order of services?',      runlevels  => 'Set overrides for start-up order of services?',
     firewall   => 'Configure firewall settings for Apache',      firewall   => 'Configure firewall settings for Apache',
     stopsrvcs  => 'Stop extra services not required on a LON-CAPA server?',      stopsrvcs  => 'Stop extra services not required on a LON-CAPA server?',
     download   => 'Download LON-CAPA source code in readiness for installation?',      download   => 'Download LON-CAPA source code in readiness for installation?',
 );  );
   
 print "\n".&mt('Checking system status ...')."\n";  print "\n".&mt('Checking system status ...')."\n\n";
   
 my $dsn = "DBI:mysql:database=mysql";  my $dsn = "DBI:mysql:database=mysql";
 my ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,$mysqlrestart,  my ($distro,$gotprereqs,$localecmd,$packagecmd,$updatecmd,$installnow,$mysqlrestart,
     $recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus,$filetouse,$production,      $recommended,$dbh,$has_pass,$has_lcdb,$downloadstatus,$filetouse,$production,
     $testing,$apachefw,$uses_systemctl) = &check_required($instdir,$dsn);      $testing,$apachefw,$uses_systemctl,$hostname) = &check_required($instdir,$dsn);
 if ($distro eq '') {  if ($distro eq '') {
     print "\n".&mt('Linux distribution could not be verified as a supported distribution.')."\n".      print "\n".&mt('Linux distribution could not be verified as a supported distribution.')."\n".
           &mt('The following are supported: [_1].',            &mt('The following are supported: [_1].',
Line 1312  if (!$gotprereqs) { Line 1393  if (!$gotprereqs) {
           &mt('The following command can be used to install the package (and dependencies):')."\n\n".            &mt('The following command can be used to install the package (and dependencies):')."\n\n".
           $updatecmd."\n\n";            $updatecmd."\n\n";
     if ($installnow eq '') {      if ($installnow eq '') {
         print &mt('Stopping execution.')."\n";  
         exit;          exit;
     } else {      } else {
         print &mt('Run command? ~[Y/n~]');          print &mt('Run command? ~[Y/n~]');
Line 1452  if ($dbh) { Line 1532  if ($dbh) {
   
 if ($callsub{'apache'}) {  if ($callsub{'apache'}) {
     if ($distro =~ /^(suse|sles)/) {      if ($distro =~ /^(suse|sles)/) {
         &copy_apache2_suseconf($instdir);          &copy_apache2_suseconf($instdir,$hostname);
     } elsif ($distro =~ /^(debian|ubuntu)/) {      } elsif ($distro =~ /^(debian|ubuntu)/) {
         &copy_apache2_debconf($instdir,$distro);          &copy_apache2_debconf($instdir,$distro,$hostname);
     } else {      } else {
         &copy_httpd_conf($instdir,$distro);          &copy_httpd_conf($instdir,$distro,$hostname);
     }      }
 } else {  } else {
     print_and_log(&mt('Skipping configuration of Apache web server.')."\n");      print_and_log(&mt('Skipping configuration of Apache web server.')."\n");
 }  }
   
   if ($callsub{'apachessl'}) {
       if ($distro =~ /^(suse|sles)/) {
           &copy_apache_sslconf_file($instdir,'/etc/apache2/vhosts.d',$hostname);
       } elsif ($distro =~ /^(debian|ubuntu)/) {
           my $apache2_sites_available_dir = '/etc/apache2/sites-available';
           if (&copy_apache_sslconf_file($instdir,$apache2_sites_available_dir,$hostname)) {
               my $apache2_sites_enabled_dir = '/etc/apache2/sites-enabled';
               my $made_symlink =  eval { symlink("$apache2_sites_available_dir/loncapassl.conf","$apache2_sites_enabled_dir/loncapassl.conf"); 1 };
               if ($made_symlink) {
                   print_and_log(&mt('Enabling "[_1]" Apache SSL configuration.','loncapassl.conf')."\n");  
               }
           }
       } else {
           &copy_apache_sslconf_file($instdir,'/etc/httpd/conf.d',$hostname);
       }
       print_and_log("\n");
   } else {
       print_and_log(&mt('Skipping configuration of SSL for Apache web server.')."\n");
   }
   
 if ($callsub{'runlevels'}) {  if ($callsub{'runlevels'}) {
     my $count = 0;      my $count = 0;
     if (ref($recommended) eq 'HASH') {      if (ref($recommended) eq 'HASH') {
Line 1522  if ($callsub{'firewall'}) { Line 1622  if ($callsub{'firewall'}) {
 }  }
   
 if ($callsub{'stopsrvcs'}) {  if ($callsub{'stopsrvcs'}) {
     &kill_extra_services($distro,$recommended->{'stopsrvcs'});      &kill_extra_services($distro,$recommended->{'stopsrvcs'},$uses_systemctl);
 } else {  } else {
     &print_and_log(&mt('Skipping stopping unnecessary service ([_1] daemons).',"'cups','memcached'")."\n");      &print_and_log(&mt('Skipping stopping unnecessary service ([_1] daemons).',"'cups','memcached'")."\n");
 }  }
Line 1709  END Line 1809  END
 }  }
   
 sub kill_extra_services {  sub kill_extra_services {
     my ($distro,$stopsrvcs) = @_;      my ($distro,$stopsrvcs,$uses_systemctl) = @_;
     if (ref($stopsrvcs) eq 'HASH') {      if (ref($stopsrvcs) eq 'HASH') {
         my @stopping = sort(keys(%{$stopsrvcs}));          my @stopping = sort(keys(%{$stopsrvcs}));
         if (@stopping) {          if (@stopping) {
Line 1740  sub kill_extra_services { Line 1840  sub kill_extra_services {
                         }                          }
                     }                      }
             &print_and_log(&mt('Removing [_1] from startup.',$service)."\n");              &print_and_log(&mt('Removing [_1] from startup.',$service)."\n");
                     if ($distro =~ /^(debian|ubuntu)/) {                      if ($distro =~ /^(?:debian|ubuntu)(\d+)/) {
                         &print_and_log(`update-rc.d -f $daemon remove`);                          my $version = $1;
                           if (($distro =~ /^ubuntu/) && ($version > 16)) {
                               if (ref($uses_systemctl) eq 'HASH') {
                                   if ($uses_systemctl->{$service}) {
                                       if (`systemctl is-enabled $service`) {
                                           &print_and_log(`systemctl disable $service`);
                                       }
                                   }
                               }
                           } else {
                               &print_and_log(`update-rc.d -f $daemon remove`);
                           }
                     } else {                      } else {
                         if (ref($uses_systemctl) eq 'HASH') {                          if (ref($uses_systemctl) eq 'HASH') {
                             if ($uses_systemctl->{$service}) {                              if ($uses_systemctl->{$service}) {
Line 1807  sub setup_mysql_permissions { Line 1918  sub setup_mysql_permissions {
         }          }
     }      }
     if ($usesauth) {      if ($usesauth) {
         @mysql_commands = ("INSERT user (Host, User, ssl_cipher, x509_issuer, x509_subject) VALUES('localhost','www','','','')",          @mysql_commands = ("INSERT user (Host, User, ssl_cipher, x509_issuer, x509_subject, authentication_string) VALUES('localhost','www','','','','')",
                          "ALTER USER 'www'\@'localhost' IDENTIFIED BY 'localhostkey'");                           "ALTER USER 'www'\@'localhost' IDENTIFIED WITH mysql_native_password BY 'localhostkey'");
     } elsif ($hasauthcol) {      } elsif ($hasauthcol) {
         @mysql_commands = ("INSERT user (Host, User, Password, ssl_cipher, x509_issuer, x509_subject, authentication_string) VALUES('localhost','www',password('localhostkey'),'','','','');");          @mysql_commands = ("INSERT user (Host, User, Password, ssl_cipher, x509_issuer, x509_subject, authentication_string) VALUES('localhost','www',password('localhostkey'),'','','','');");
     } else {      } else {
Line 1863  INSERT db (Host,Db,User,Select_priv,Inse Line 1974  INSERT db (Host,Db,User,Select_priv,Inse
             }              }
         }          }
         if ($got_passwd) {          if ($got_passwd) {
             my (@newpass_cmds) = &new_mysql_rootpasswd($newmysqlpass);              my (@newpass_cmds) = &new_mysql_rootpasswd($newmysqlpass,$usesauth);
             push(@mysql_commands,@newpass_cmds);              push(@mysql_commands,@newpass_cmds);
         } else {          } else {
             print_and_log(&mt('Failed to get MySQL root password from user input.')."\n");              print_and_log(&mt('Failed to get MySQL root password from user input.')."\n");
Line 1872  INSERT db (Host,Db,User,Select_priv,Inse Line 1983  INSERT db (Host,Db,User,Select_priv,Inse
             if (@mysql_commands) {              if (@mysql_commands) {
                 foreach my $cmd (@mysql_commands) {                  foreach my $cmd (@mysql_commands) {
                     $dbh->do($cmd) || print $dbh->errstr."\n";                      $dbh->do($cmd) || print $dbh->errstr."\n";
   
                 }                  }
             }              }
             if (@mysql_lc_commands) {              if (@mysql_lc_commands) {
Line 1896  INSERT db (Host,Db,User,Select_priv,Inse Line 2006  INSERT db (Host,Db,User,Select_priv,Inse
 sub new_mysql_rootpasswd {  sub new_mysql_rootpasswd {
     my ($currmysqlpass,$usesauth) = @_;      my ($currmysqlpass,$usesauth) = @_;
     if ($usesauth) {      if ($usesauth) {
         return ("ALTER USER 'root'\@'localhost' IDENTIFIED BY '$currmysqlpass'",          return ("ALTER USER 'root'\@'localhost' IDENTIFIED WITH mysql_native_password BY '$currmysqlpass'",
                 "FLUSH PRIVILEGES;");                  "FLUSH PRIVILEGES;");
     } else {      } else {
         return ("SET PASSWORD FOR 'root'\@'localhost'=PASSWORD('$currmysqlpass')",          return ("SET PASSWORD FOR 'root'\@'localhost'=PASSWORD('$currmysqlpass')",
Line 1926  sub get_mysql_version { Line 2036  sub get_mysql_version {
 ###########################################################  ###########################################################
   
 sub copy_httpd_conf {  sub copy_httpd_conf {
     my ($instdir,$distro) = @_;      my ($instdir,$distro,$hostname) = @_;
     my $configfile = 'httpd.conf';      my $configfile = 'httpd.conf';
     if ($distro =~ /^(?:centos|rhes|scientific)(\d+)$/) {      if ($distro =~ /^(?:centos|rhes|scientific)(\d+)$/) {
         if ($1 >= 7) {          if ($1 >= 7) {
Line 1949  sub copy_httpd_conf { Line 2059  sub copy_httpd_conf {
     print_and_log("\n");      print_and_log("\n");
 }  }
   
   ###############################################
   ##
   ## Copy/Modify loncapassl.conf
   ##
   ###############################################
   
   sub copy_apache_sslconf_file {
       my ($instdir,$targetdir,$hostname) = @_;
       my ($success,$error);
       if (-e "$instdir/loncapassl.conf") {
           if (open(my $fh,'<',"$instdir/loncapassl.conf")) {
               if (open(my $out,'>',"$targetdir/loncapassl.conf")) {
                   while (<$fh>) {
                       if (/^\QServerName internal-\E/) {
                           chomp();
                           s/^(\QServerName internal-\E)(.*)$/$1$hostname\n/;
                       }
                       print $out $_;
                   }
                   $success = 1;
               } else {
                   $error = "Could not write to $targetdir/loncapassl.conf";
               }
           } else {
               $error = "Could not read from $instdir/loncapassl.conf";
           }
       } else {
           $error = "File to copy from: $instdir/loncapassl.conf does not exist";
       }
       if ($success) {
           print_and_log(&mt('Successfully copied [_1] to [_2].',"'loncapassl.conf'","'$targetdir/loncapassl.conf'")."\n");
           chmod(0444,"$targetdir/loncapassl.conf");
       } else {
           print_and_log(&mt('Failed to copy [_1] to [_2].',"'loncapassl.conf'","'$targetdir/loncapassl.conf'")."\n");
           if ($error) {
               print_and_log("$error\n");
           }
       }
       return $success;
   }
   
 #########################################################  #########################################################
 ##  ##
 ## Ubuntu/Debian -- copy our loncapa configuration file to  ## Ubuntu/Debian -- copy our loncapa configuration file to
Line 1957  sub copy_httpd_conf { Line 2108  sub copy_httpd_conf {
 #########################################################  #########################################################
   
 sub copy_apache2_debconf {  sub copy_apache2_debconf {
     my ($instdir,$distro) = @_;      my ($instdir,$distro,$hostname) = @_;
     my $apache2_mods_enabled_dir = '/etc/apache2/mods-enabled';      my $apache2_mods_enabled_dir = '/etc/apache2/mods-enabled';
     my $apache2_mods_available_dir = '/etc/apache2/mods-available';      my $apache2_mods_available_dir = '/etc/apache2/mods-available';
     foreach my $module ('headers.load','expires.load') {      foreach my $module ('headers.load','expires.load') {
Line 2019  sub copy_apache2_debconf { Line 2170  sub copy_apache2_debconf {
 ###########################################################  ###########################################################
   
 sub copy_apache2_suseconf {  sub copy_apache2_suseconf {
     my ($instdir) = @_;      my ($instdir,$hostname) = @_;
     print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',      print_and_log(&mt('Copying the LON-CAPA [_1] to [_2].',
                   "'default-server.conf'",                    "'default-server.conf'",
                   "'/etc/apache2/default-server.conf'")."\n");                    "'/etc/apache2/default-server.conf'")."\n");

Removed from v.1.43  
changed lines
  Added in v.1.46


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>