[LON-CAPA-cvs] cvs: doc /loncapafiles updatequery.piml

raeburn raeburn at source.lon-capa.org
Mon Aug 17 18:18:44 EDT 2026


raeburn		Mon Aug 17 22:18:44 2026 EDT

  Modified files:              
    /doc/loncapafiles	updatequery.piml 
  Log:
  - Add "Accessibility Checking Available" item to configuration items.
    - Stored in /etc/httpd/conf/loncapa.conf or /etc/apache2/loncapa.conf 
      PerlSetVar  lonAxeUse  Y
      PerlSetVar  lonAxeUse  N
    - Default is N. If Y entered, appropriate nodejs and browser packages will
      be installed after configuring any required repos and/or enabling
      modules (depending on distro).
  
  
-------------- next part --------------
Index: doc/loncapafiles/updatequery.piml
diff -u doc/loncapafiles/updatequery.piml:1.103 doc/loncapafiles/updatequery.piml:1.104
--- doc/loncapafiles/updatequery.piml:1.103	Mon Aug 17 22:02:39 2026
+++ doc/loncapafiles/updatequery.piml	Mon Aug 17 22:18:44 2026
@@ -1,6 +1,6 @@
 <!-- updatequery.piml -->
 
-<!-- $Id: updatequery.piml,v 1.103 2026/08/17 22:02:39 raeburn Exp $ -->
+<!-- $Id: updatequery.piml,v 1.104 2026/08/17 22:18:44 raeburn Exp $ -->
 
 <!--
 
@@ -43,6 +43,7 @@
 use Storable qw(thaw);
 use Term::ReadKey;
 use Locale::Country;
+use IPC::Cmd qw(can_run);
 
 sub get_new_sslkeypass {
     my $sslkeypass;
@@ -59,10 +60,14 @@
     return $sslkeypass;
 }
 
-sub get_static_config {
 # get LCperlvars from loncapa_apache.conf
+
+sub get_static_config {
+    my ($dist,$version) = @_;
     my $confdir = '/etc/httpd/conf/';
-    if ('<DIST />' eq 'sles10' || '<DIST />' eq 'sles11' || '<DIST />' eq 'sles12' || '<DIST />' eq 'sles15' || '<DIST />' eq 'sles16' || '<DIST />' eq 'suse10.1' || '<DIST />' eq 'suse10.2' || '<DIST />' eq 'suse10.3' || '<DIST />' eq 'suse11.1' || '<DIST />' eq 'suse11.2' || '<DIST />' eq 'suse11.3' || '<DIST />' eq 'suse11.4' || '<DIST />' eq 'suse12.1' || '<DIST />' eq 'suse12.2' || '<DIST />' eq 'suse12.3' || '<DIST />' eq 'suse13.1' || '<DIST />' eq 'suse13.2' || '<DIST />' eq 'debian5' || '<DIST />' eq 'debian6' || '<DIST />' eq 'ubuntu6' || '<DIST />' eq 'ubuntu8' || '<DIST />' eq 'ubuntu10' || '<DIST />' eq 'ubuntu12' || '<DIST />' eq 'ubuntu14' || '<DIST />' eq 'ubuntu16' || '<DIST />' eq 'ubuntu18' || '<DIST />' eq 'ubuntu20' || '<DIST />' eq 'ubuntu22' || '<DIST />' eq 'ubuntu24' || '<DIST />' eq 'ubuntu26' || '<DIST />' eq 'debian10' || '<DIST />' eq 'debian11' || '<DIST />' eq 'debian12' || '<DIST />' eq 'debian13') {
+    if ((($dist eq 'sles') && ($version > 9)) ||
+        (($dist eq 'suse') && ($version >= 10.1)) ||
+        ($dist eq 'debian') || ($dist eq 'ubuntu')) {
         $confdir = '/etc/apache2/';
     }
     my $filename='loncapa_apache.conf';
@@ -660,6 +665,335 @@
     return ($output,$lonkeystatus,$lonhostcertstatus,$lonhostnamecertstatus,\%sslstatus);
 }
 
+sub get_axe_status {
+    my ($dist,$version,$statusref,$installref) =@_;
+    return unless ((ref($statusref) eq 'HASH') && (ref($installref) eq 'HASH'));
+    my ($browser,$nodeversion,$npmversion,$npmmajor);
+    my $nodejs = can_run('node');
+    if ($nodejs) {
+        if (open(my $pipe, '-|','node -v')) {
+            $nodeversion = <$pipe>;
+            chomp($nodeversion);
+            $statusref->{'nodejs'} = $nodeversion;
+            close($pipe);
+        }
+    }
+    my $npm = can_run('npm');
+    if ($npm) {
+        if (open(my $pipe, '-|','npm -v')) {
+            $npmversion = <$pipe>;
+            chomp($npmversion);
+            $statusref->{'npm'} = $npmversion;
+            ($npmmajor) = ($npmversion =~ /^(\d+)./);
+            close($pipe);
+        }
+    }
+    if ($dist eq 'ubuntu') {
+        if ($version >= 24) {
+            unless (($npm) && ($npmmajor >= 8)){
+                $installref->{'npm'} = 1;
+            }
+            unless (($nodejs) && ($nodeversion >= 18)) {
+                $installref->{'nodejs'} = 1;
+            }
+        } else {
+            unless (($nodejs) && ($nodeversion >= 17)) {
+                $installref->{'nodesource'} = 1;
+            }
+        }
+        if ($version >= 22) {
+            $browser = '/usr/bin/google-chrome-stable';
+        } elsif ($version == 20) {
+            $browser = '/usr/bin/chromium';
+        }
+    } elsif ($dist eq 'debian') { 
+        if ($version > 10) {
+            $browser = '/usr/bin/chromium';
+            if ($version > 11) {
+                unless (($npm) && ($npmmajor >= 9)) {
+                    $installref->{'npm'} = 1;
+                }
+                unless (($nodejs) && ($nodeversion >= 18)) {
+                    $installref->{'nodejs'} = 1;
+                }
+            } else {
+                unless (($nodejs) && ($nodeversion >= 24)) {
+                    $installref->{'nodesource'} = 1;
+                }
+            }
+        }
+    } elsif ($dist eq 'sles') {
+        if ($version > 12) {
+            $browser = '/usr/bin/chromium-browser';
+            unless (($nodejs) && ($nodeversion >= 24)) {
+                $installref->{'nodejs24'} = 1;
+            }
+        } elsif ($version == 12) {
+            $browser = '/usr/bin/firefox';
+            unless (($nodejs) && ($nodeversion >= 18)) {
+                $installref->{'nodejs18'} = 1;
+            }
+        }
+    } elsif ($dist =~ /^(?:rhes|oracle|alma|rocky|centos|scientific)$/) {
+        if ($version > 7) {
+            $browser = '/usr/bin/chromium-browser';
+            if ($version < 10) {
+                unless (($nodejs) && ($nodeversion >= 24)) {
+                    $installref->{'nodejs'} = 1;
+                }
+            } else {
+                unless (($nodejs) && ($nodeversion >= 22)) {
+                    $installref->{'nodejs'} = 1;
+                }
+            }
+        } elsif ($version == 7) {
+            $browser = '/usr/bin/firefox';
+            unless (($nodejs) && ($nodeversion >= 24)) {
+                $installref->{'nodejs'} = 1;
+            }
+        }
+    } elsif ($dist eq 'centos-stream') {
+        if ($version < 10) {
+            unless (($nodejs) && ($nodeversion >= 24)) {
+                $installref->{'nodejs'} = 1;
+            }
+        } else {
+            unless (($nodejs) && ($nodeversion >= 22)) {
+                $installref->{'nodejs'} = 1;
+            }
+        }
+        $browser = '/usr/bin/chromium-browser';
+    } elsif ($dist eq 'fedora') {
+        if ($version > 39) {
+            $browser = '/usr/bin/chromium-browser';
+            unless (($nodejs) && ($nodeversion >= 24)) {
+                $installref->{'nodejs24'} = 1;
+            }
+        }
+    }
+    unless ($browser eq '') {
+        if (-e $browser) {
+            $statusref->{'browser'} = 'ok';
+        } else {
+            $installref->{$browser} = 1;
+        }
+        if ($npm) {
+            my $original_dir = cwd();
+            if (chdir '/home/httpd/node.js/axe') {
+                if (open(my $pipe, '-|','npm ls puppeteer axe-core')) {
+                    while (my $line = <$pipe>) {
+                        chomp($line);
+                        if ($line =~ /(puppeteer|axe-core)\@[\d.]+$/) {
+                            $statusref->{$1} = 'ok';
+                        }
+                    }
+                    close($pipe);
+                }
+                chdir $original_dir;
+            }
+        }
+    }
+}
+
+sub enable_nodesource {
+    my ($dist,$version,$arch) = @_;
+    my $repo_enabled;
+    my ($sep,$title,$nodesource,$gpgkey, at keyorder, at currorder,%expected,%actual,%origcase,
+        %actual,%origcase,%wrongvalue,%missing,%extra,%modifyextra);
+    return unless($dist =~ /^(ubuntu|debian|fedora|rhes|oracle|alma|rocky|centos|centos\-stream|scientific)$/);
+    if (($dist eq 'ubuntu') || ($dist eq 'debian')) {
+        $sep = ':';
+        $nodesource = '/etc/apt/sources.list.d/nodesource.sources';
+        $gpgkey = '/etc/apt/keyrings/nodesource.gpg';
+        @keyorder = qw(Types URIs Suites Components Architectures Signed-By);
+        %expected = (
+                       Types         => 'deb',
+                       URIs          => 'https://deb.nodesource.com/node_24.x',
+                       Suites        => 'nodistro',
+                       Components    => 'main',
+                       Architectures => 'amd64',
+                       SignedBy      => '/etc/apt/keyrings/nodesource.gpg',
+                    );
+        unless (-e '/etc/apt/keyrings/nodesource.gpg') {
+            if (open(my $pipe, '-|',"curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg")) {
+                my $result = <$pipe>;
+                close($pipe);
+            }
+        }   
+        $nodesource = '/etc/apt/sources.list.d/nodesource.sources';
+    } elsif ($dist =~ /^(fedora|rhes|oracle|alma|rocky|centos|centos\-stream|scientific)$/) {
+        $sep = '=';
+        $nodesource = '/etc/yum.repos.d/nodesource-nodejs.repo';
+        $gpgkey = '';
+        $title = '[nodesource-nodejs]';
+        @keyorder = qw(name baseurl priority enabled gpgcheck gpgkey module_hotfixes);
+        %expected = (
+                       name            => 'Node.js Packages for Linux RPM based distros -'.$arch,
+                       baseurl         => 'https://rpm.nodesource.com/pub_24.x/nodistro/nodejs/'.$arch,
+                       priority        => 9,
+                       enabled         => 1,
+                       gpgcheck        => 1, 
+                       gpgkey          => 'https://rpm.nodesource.com/gpgkey/ns-operations-public.key',
+                       module_hotfixes => 1,
+                    );
+        if (open(my $pipe, '-|',"rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} -- %{summary}\n'")) {
+            while (my $line = <$pipe>) {
+                chomp($line);
+                if ($line =~ /<operations\@nodesource\.com>/) {
+                    if ($line =~ /^(\Qgpg-pubkey-\E[\S]+)\s+/) {
+                        $gpgkey = $1;
+                    }
+                    last;
+                }
+            }
+            close($pipe);
+        }
+        unless ($gpgkey) {
+            if ($expected{'gpgkey'} ne '') {
+                if (open(my $pipe, '-|',"rpm --import $expected{'gpgkey'}")) {
+                    my $result = <$pipe>;
+                    close($pipe);
+                }
+            }
+        }
+    }
+    if (-e $nodesource) {
+        if (open(my $fh,'<',$nodesource)) {
+            while (my $line = <$fh>) {
+                my ($key,$value) = split(/\Q$sep\E/,$line,2);
+                $key =~ s/(^\s+|\s+$)//g;
+                $value = s/(^\s+|\s+$)//g;
+                my $lckey = lc($key);
+                push(@currorder,$lckey);
+                $actual{$lckey} = $value;
+                if ($lckey ne $key) {
+                    $origcase{$lckey} = $key;
+                }
+            }
+            close($fh);
+            foreach my $key (keys(%expected)) {
+                my $lckey = lc($key);
+                if (exists($actual{$lckey})) {
+                    unless ($actual{$lckey} eq $expected{$lckey}) {
+                        $wrongvalue{$key} = 1;
+                    }
+                } else {
+                    $missing{$key} = 1;
+                }
+            }
+            foreach my $key (keys(%actual)) {
+                next if (grep(/^\Q$key$\E/, map { lc($_); } @keyorder));
+                if (($key eq 'enabled') && ($actual{$key} =~ /^no$/i)) {
+                    $extra{'enabled'} = 'yes';
+                    $modifyextra{$key} = 1;
+                }
+            }
+            if ($dist =~ /^(ubuntu|debian)/) {
+                $sep .= ' ';
+            }
+            if ((keys(%wrongvalue)) || (keys(%missing)) || (keys(%modifyextra))) {
+                if (open(my $fh,'>',$nodesource)) {
+                    if (@currorder) {
+                        foreach my $key (@currorder) {
+                            if (exists($origcase{$key})) {
+                                print $fh $origcase{$key}.$sep;
+                            } else {
+                                print $fh $key.$sep;
+                            }
+                            if (exists($wrongvalue{$key})) {
+                                print $fh $expected{$key};
+                            } elsif ($modifyextra{$key}) {
+                                print $fh $extra{$key};
+                            } else {
+                                print $fh $actual{$key};
+                            }
+                            print $fh "\n";
+                        }
+                        if (keys(%missing)) {
+                            foreach my $key (sort(keys(%missing))) {
+                                print $fh $key.$sep.$expected{$key}."\n";
+                            }
+                        }
+                    } else {
+                        foreach my $key (@keyorder) {
+                            print $fh $key.$sep.$expected{$key}."\n";
+                        }
+                    }
+                    close($fh);
+                    $repo_enabled = 1;
+                } else {
+                    print "Could not write to $nodesource\n";
+                }
+            } else {
+                $repo_enabled = 1;
+            }
+        } else {
+            print "Could not open $nodesource\n";
+        }
+    } else {
+        if (open(my $fh,'>',$nodesource)) {
+            foreach my $key (@keyorder) {
+                print $fh $key.$sep.$expected{$key}."\n";
+            }
+            close($fh);
+            $repo_enabled = 1;
+        } else {
+            print "Could not open $nodesource\n";
+        }
+    }
+    return $repo_enabled;
+}
+
+sub axe_info {
+   print(<<END);
+
+****** Information about Accessibility Checking using Axe *****
+
+If you would like Course Coordinators to be able
+to use a "Check for Accessibility" link, accessed via
+Course Editor > Content Utilities, some  
+additional packages may need to be installed, if not
+already present.  
+
+The packages include a modern version of node.js,
+and a headless browser (which will be chromium unless 
+unless your Linux distro/version requires use of 
+either google chrome or firefox).
+
+The total amount of disk space needed is about 1GB.
+In addition, chromium (and other web browsers)
+are regularly updated, so you'll receive regular
+email from the CHECKRPMS script (which checks if rpms, 
+or debs on Ubuntu/Debian, need updating). 
+
+If you choose to support Accessibility Checking and
+this is going to be a LON-CAPA library server, 
+Authors and Co-authors will also be able to use
+an "Accessibility" link in the Functions menu
+displayed when listing a directory in Authoring
+Space.
+
+END
+}
+
+sub axe_action {
+   print(<<END);
+
+As you responded "Y" to the prompt to support Accessibility
+Checking any additional repos required for your particular 
+Linux distribution/version will be enabled, and rpms or debs
+(Ubuntu or Debian) will be downloaded and installed.
+The installation process may take a couple of minutes.
+
+With those in place, the final action of the ./UPDATE
+process will be to run a script using the Node Package
+Manager (npm) to retrieve javascript libraries for
+Puppeteer, Axe-core and dependencies. That final step
+may take an additional minute or two.
+
+END
+}
+
   print(<<END);
 
 
@@ -781,6 +1115,17 @@
 my $state;
 my $country;
 my @libservers = ();
+my $installAxe;
+
+my ($dist,$version);
+my $distro = '<DIST />';
+if ($distro =~ /^centos(\d+)\-stream$/) {
+    $version = $1;
+    $dist = 'centos-stream';
+} else {
+    ($dist,$version) = ($distro =~ /^([A-Za-z]+)([\d\.]+)$/);
+}
+
 unless (-e "<TARGET />") {
   print(<<END);
            WELCOME TO LON-CAPA!
@@ -798,6 +1143,7 @@
 * Web Server Protocol
 * Internet Domain Name of Your Institution
 * Hostname
+* Axe Accessibility Checker Use
 * City, State, Country for LON-CAPA SSL certificate 
 * Password for key for creating SSL certificates
 ===============================================================================
@@ -1250,6 +1596,32 @@
   }
 }
 
+&axe_info();
+
+$flag=0;
+while (!$flag) {
+  print(<<END);
+
+****  Support Accessibility Checker on this Machine ****
+
+ENTER Y or N:
+END
+
+  my $choice=<>;
+  chomp($choice);
+  $choice =~ s/(^\s+|\s+)$//g; 
+  if ($choice =~/^Y|N$/) {
+    open(OUT,'>>/tmp/loncapa_updatequery.out');
+    print(OUT 'accessibility checking'."\t".$choice."\n");
+    close(OUT);
+    $installAxe=$choice;
+    $flag=1;
+  }
+  else {
+    print "Invalid input (must be either Y or N) -- Y to support accessibility checking, or N to not support it).\n";
+  }
+}
+
 &ssl_info();
 
 $country = &get_country($desiredhostname);
@@ -1260,7 +1632,7 @@
 
 ($domainDescription,$country,$state,$city) = &confirm_locality($domainDescription,$country,$state,$city);
 
-my $perlstaticref = &get_static_config();
+my $perlstaticref = &get_static_config($dist,$version);
 if (ref($perlstaticref) eq 'HASH') {
   my ($certsdir,$privkey,$connectcsr,$replicatecsr);
   $certsdir = $perlstaticref->{'lonCertificateDirectory'};
@@ -1304,9 +1676,11 @@
 
 # update loncapa.conf
 my $confdir = '/etc/httpd/conf/';
-if ('<DIST />' eq 'sles10' || '<DIST />' eq 'sles11' || '<DIST />' eq 'sles12' || '<DIST />' eq 'sles15' || '<DIST />' eq 'sles16' || '<DIST />' eq 'suse10.1' || '<DIST />' eq 'suse10.2' || '<DIST />' eq 'suse10.3' || '<DIST />' eq 'suse11.1' || '<DIST />' eq 'suse11.2' || '<DIST />' eq 'suse11.3' || '<DIST />' eq 'suse11.4' || '<DIST />' eq 'suse12.1' || '<DIST />' eq 'suse12.2' || '<DIST />' eq 'suse12.3' || '<DIST />' eq 'suse13.1' || '<DIST />' eq 'suse13.2' || '<DIST />' eq 'debian5' || '<DIST />' eq 'debian6' || '<DIST />' eq 'ubuntu6' || '<DIST />' eq 'ubuntu8' || '<DIST />' eq 'ubuntu10' || '<DIST />' eq 'ubuntu12' || '<DIST />' eq 'ubuntu14' || '<DIST />' eq 'ubuntu16' || '<DIST />' eq 'ubuntu18' || '<DIST />' eq 'ubuntu20' || '<DIST />' eq 'ubuntu22' || '<DIST />' eq 'ubuntu24' || '<DIST />' eq 'ubuntu26' || '<DIST />' eq 'debian10' || '<DIST />' eq 'debian11' || '<DIST />' eq 'debian12' || '<DIST />' eq 'debian13') {
-     $confdir = '/etc/apache2/';
-}   
+if ((($dist eq 'sles') && ($version > 9)) || 
+    (($dist eq 'suse') && ($version >= 10.1)) || 
+    ($dist eq 'debian') || ($dist eq 'ubuntu')) {
+    $confdir = '/etc/apache2/';
+}
 my $filename='loncapa.conf';
 my %perlvar;
     if (-e "$confdir$filename") {
@@ -1325,6 +1699,7 @@
     $perlvar{'lonAdmEMail'}=$lonAdmEMail;
     $perlvar{'lonSupportEMail'}=$lonSupportEMail;
     $perlvar{'lonRole'}=$lonRole;
+    $perlvar{'lonAxeUse'}=$installAxe;
     unless ($perlvar{'lonLoadLim'} and $perlvar{'lonLoadLim'}!~/\{\[\[\[\[/) {
        $perlvar{'lonLoadLim'}='2.00';
     }
@@ -1343,6 +1718,9 @@
        }
        $perlvar{'lonReceipt'}=$lonReceipt;
     }
+    unless ($perlvar{'lonAxeUse'} and $perlvar{'lonAxeUse'}!~/\{\[\[\[\[/) {
+       $perlvar{'lonAxeUse'}='N';
+    }
     open(OUT,">$confdir$filename") or
       die("Cannot output to $confdir$filename\n");
     foreach my $key (keys %perlvar) {
@@ -1394,6 +1772,9 @@
     unless ($perlvar{'loncAllowInsecure'} and $perlvar{'loncAllowInsecure'}!~/\{\[\[\[\[/) {
        $perlvar{'loncAllowInsecure'}='1';
     }
+    unless ($perlvar{'lonAxeUse'} and $perlvar{'lonAxeUse'}!~/\{\[\[\[\[/) {
+       $perlvar{'lonAxeUse'} ='N';
+    }
     my ($securestatus,$securenum)=&securesetting(%perlvar);
     unless ($perlvar{'lonReceipt'} and $perlvar{'lonReceipt'}!~/\{\[\[\[\[/) {
        my $lonReceipt='';
@@ -1404,7 +1785,7 @@
        }
        $perlvar{'lonReceipt'}=$lonReceipt;
     }
-    my $perlvarstatic = &get_static_config();
+    my $perlvarstatic = &get_static_config($dist,$version);
 
     my (@hosts_files, @domain_files);
     if ( $lonCluster ne 'existing') {
@@ -1530,7 +1911,7 @@
 my $flag=0;
 
 #
-# Changes to 5, 6, and 14 not supported if configuration.db set on primary library server.
+# Changes to 5, 6, and 15 not supported if configuration.db set on primary library server.
 # (requires either this machine to be primary library server or for LON-CAPA and Apache
 # to be running on primary library server).
 #
@@ -1642,11 +2023,12 @@
 11) Cache Expiration Time: $perlvar{'lonExpire'} (seconds)
 12) Server Load: $perlvar{'lonLoadLim'}
 13) User Load: $perlvar{'lonUserLoadLim'}
-14) LON-CAPA "internal" connections: $securestatus
-15) Private Key for SSL: $lonkeystatus
-16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
-17) SSL Certificate for Content Replication: $lonhostnamecertstatus
-18) Everything is correct up above
+14) Accessibility Checking Available: $perlvar{'lonAxeUse'} 
+15) LON-CAPA "internal" connections: $securestatus
+16) Private Key for SSL: $lonkeystatus
+17) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
+18) SSL Certificate for Content Replication: $lonhostnamecertstatus
+19) Everything is correct up above
 END
 
 my @error;
@@ -1720,7 +2102,7 @@
 
 if (@error) { print "\n*** ERRORS: \n\t".join("\n\t", at error)."\n"; }
   print(<<END);
-ENTER A CHOICE OF 1-17 TO CHANGE, otherwise ENTER 18:
+ENTER A CHOICE OF 1-18 TO CHANGE, otherwise ENTER 19:
 END
 my $choice=<>;
 chomp($choice);
@@ -1868,7 +2250,7 @@
   elsif ($choice==13) {
   print(<<END);
 13) User Load: $perlvar{'lonUserLoadLim'}
-Numer of users that can login before machine is 'overloaded'
+Number of users that can login before machine is 'overloaded'
 ENTER NEW VALUE (integer value, 0 means there is no limit):
 END
     my $choice2=<>;
@@ -1876,14 +2258,40 @@
     $perlvar{'lonUserLoadLim'}=$choice2;
   }
   elsif ($choice==14) {
+    my $curr_axe = $perlvar{'lonAxeUse'}; 
+  
+    print(<<END);
+14) Accessibility Checking Available: $perlvar{'lonAxeUse'}
+
+ENTER NEW VALUE: Y or N (Y means "Yes"; N means "No")  
+END
+    my $choice2=<>;
+    chomp($choice2);
+    $choice2 =~ s/(^\s+|\s+$)//g;
+
+    if ($choice2 =~ /^Y/) {
+        $choice2 = 'Y';
+    } else {
+        $choice2 = 'N';
+    }
+    $perlvar{'lonAxeUse'}=$choice2;
+
+    if (($choice2 eq 'Y') && ($curr_axe ne 'Y')) {
+        if ($installAxe eq '') {
+            &axe_info();
+        }
+        &axe_action();
+    }
+  }
+  elsif ($choice==15) {
     if ($setbygui{'securestatus'}) {
       print(<<END);
-14) Allow only secure connections: $securestatus
+15) Allow only secure connections: $securestatus
 Use the web GUI (as domain coordinator) to make changes after completing the UPDATE.
 END
     } else {
       print(<<END);
-14) Allow only secure connections: $securestatus 
+15) Allow only secure connections: $securestatus 
 The Lon-CAPA communication daemons lonc and lond can be configured to
 allow only secure connections by default.
 
@@ -1910,10 +2318,10 @@
       }
       ($securestatus,$securenum)=&securesetting(%perlvar);
     }
-  } elsif ($choice==15) {
+  } elsif ($choice==16) {
       if ($sslstatus{'key'} == 1) {
           print(<<END);
-15) Private Key for SSL: $lonkeystatus
+16) Private Key for SSL: $lonkeystatus
 
 POSSIBLE CHOICES:
 1) overwrite existing key
@@ -1928,7 +2336,7 @@
           }
       } elsif ($sslstatus{'key'} == 0) {
           print(<<END);
-15) Private Key for SSL: $lonkeystatus
+16) Private Key for SSL: $lonkeystatus
 END
           my $sslkeypass = &get_new_sslkeypass();
           &make_key($certsdir,$privkey,$sslkeypass);
@@ -1939,10 +2347,10 @@
               %sslstatus = %{$sslref};
           }
       }
-  } elsif ($choice==16) {
+  } elsif ($choice==17) {
       if (($sslstatus{'host'} == 1) || ($sslstatus{'host'} == 2) || ($sslstatus{'host'} == 3)) {
           print(<<END);
-16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
+17) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
 
 POSSIBLE CHOICES:
 1) create new certificate signing request with new key
@@ -1986,7 +2394,7 @@
           my $sslkeypass;
           if ($sslstatus{'key'} == 1) {
               print(<<END);
-16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
+17) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
 
 POSSIBLE CHOICES:
 1) create new certificate signing request with new key
@@ -2005,7 +2413,7 @@
               }
           } else {
               print(<<END);
-16) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
+17) SSL Certificate for LON-CAPA server connections: $lonhostcertstatus
 END
               $sslkeypass = &get_new_sslkeypass();
           }
@@ -2023,10 +2431,10 @@
               %sslstatus = %{$sslref};
           }
       }
-  } elsif ($choice==17) {
+  } elsif ($choice==18) {
       if (($sslstatus{'hostname'} == 1) || ($sslstatus{'hostname'} == 2) || ($sslstatus{'hostname'} == 3)) {
           print(<<END);
-17) SSL Certificate for Content Replication: $lonhostnamecertstatus
+18) SSL Certificate for Content Replication: $lonhostnamecertstatus
 
 POSSIBLE CHOICES:
 1) create new certificate signing request with new key
@@ -2068,7 +2476,7 @@
           my $sslkeypass;
           if ($sslstatus{'key'} == 1) {
               print(<<END);
-17) SSL Certificate for Content Replication: $lonhostnamecertstatus
+18) SSL Certificate for Content Replication: $lonhostnamecertstatus
 
 POSSIBLE CHOICES:
 1) create new certificate signing request with new key
@@ -2087,7 +2495,7 @@
               }
           } else {
               print(<<END);
-17) SSL Certificate for Content Replication: $lonhostnamecertstatus
+18) SSL Certificate for Content Replication: $lonhostnamecertstatus
 END
               $sslkeypass = &get_new_sslkeypass();
           }
@@ -2105,7 +2513,7 @@
               %sslstatus = %{$sslref};
           }
       }
-  } elsif (($choice==18) && (!@error)) {
+  } elsif (($choice==19) && (!@error)) {
     $flag=1;
   } else {
     print "Invalid input.\n";
@@ -2114,7 +2522,7 @@
 
     open(OUT,">$confdir$filename") or
       die("Cannot output to $confdir$filename\n");
-    foreach my $key (keys %perlvar) {
+    foreach my $key (keys( %perlvar)) {
       my $value=$perlvar{$key};
       my $line = "PerlSetVar     $key      $value";
       if ($value eq '') {
@@ -2125,6 +2533,295 @@
 END
     }
     close(OUT);
+
+    print "\nRetrieving status information for node.js and headless web browser ... \n\n";
+    my $arch = 'x86_64';
+    if (open(my $pipe, '-|','uname -m')) {
+       my $line = <$pipe>;
+       close($pipe);
+       chomp($line);
+       if ($line ne '') {
+           $arch = $line;
+       }
+    }
+    my (%axestatus,%axeinstall);
+    my $browser = &get_axe_status($dist,$version,\%axestatus,\%axeinstall);
+    my $slesversion;
+    if ($perlvar{'lonAxeUse'} eq 'Y') {
+        my @packages;
+        if ($axeinstall{'nodejs'}) {
+            push(@packages,'nodejs');
+        } elsif ($axeinstall{'nodejs24'}) {
+            push(@packages,'nodejs24');
+        } elsif ($axeinstall{'nodejs18'}) {
+            push(@packages,'nodejs18');
+        }
+        if ($axeinstall{'npm'}) {
+            push(@packages,'npm');
+        }
+        if ($axeinstall{'nodesource'}) {
+            @packages = ('nodejs');
+        }
+        if ($dist eq 'sles') {
+            if ($version >= 12) {
+                if ((@packages) || (($browser ne '') && ($axeinstall{$browser}))) {
+                    if (open(my $pipe, '-|',"cat /etc/os-release | grep 'VERSION_ID'")) {
+                        my $line = <$pipe>;
+                        close($pipe);
+                        chomp($line);
+                        if ($line ne '') {
+                            $slesversion = $line;
+                        }
+                        close($pipe);
+                    }
+                }
+            }
+        } 
+        if (@packages) {
+            my $packagelist = join(' ', at packages);
+            if ($axeinstall{'nodesource'}) {
+                my $repo_enabled = &enable_nodesource($dist,$version,$arch);
+                if ($repo_enabled) { 
+                    my $command;
+                    if ($dist =~ /^(ubuntu|debian)$/) {
+                        $command = 'apt-get -y install nodejs';
+                    } elsif ($dist =~ /^(fedora|rhes|oracle|alma|rocky|centos|centos-stream)$/) {
+                        $command = 'dnf install nodejs -y';
+                    }
+                    if ($command ne '') {
+                        if (open(my $pipe, '-|',$command)) {
+                            while (my $line = <$pipe>) {
+                                print $line;
+                            }
+                            close($pipe);
+                        }
+                    }
+                } else {
+                    if ($dist =~ /^(ubuntu|debian)$/) {
+                        print "Could not install $packagelist using nodesource because a nodesource.sources file could not be created.\n";
+                    } elsif ($dist =~ /^(fedora|rhes|oracle|alma|rocky|centos|centos-stream)$/) {
+                        print "Could not install $packagelist using nodesource because a nodesource.repo file could not be created.\n";
+                    }
+                }
+            } elsif ($dist eq 'sles') {
+                if ($slesversion ne '') {
+                    my ($addrepo,$repo_enabled);
+                    if ($version == 16) {
+                        $repo_enabled = 1; 
+                    } elsif (($version < 16) && ($version >= 12)) {
+                        if (open(my $pipe, '-|',"zypper lr -E | grep -i web-scripting")) {
+                            my $line = <$pipe>;
+                            close($pipe);
+                            chomp($line);
+                            if ($line eq '') {
+                                $addrepo = 1;
+                            } else {
+                                $repo_enabled = 1;
+                            }
+                        }
+                    }
+                    if ($addrepo) {
+                        my $command;
+                        if ($version == 15) {
+                            $command = "SUSEConnect -p sle-module-web-scripting/$slesversion/$arch"; 
+                        } elsif ($version == 12) {
+                            $command = "SUSEConnect -p sle-module-web-scripting/$version/$arch";
+                        }
+                        if ($command) {
+                            if (open(my $pipe, '-|',$command)) {
+                                while (my $line = <$pipe>) {
+                                    print $line;
+                                }
+                                close($pipe);
+                            }
+                            if (open(my $pipe, '-|',"zypper lr -E | grep -i web-scripting")) {
+                                my $line = <$pipe>;
+                                close($pipe);
+                                chomp($line);
+                                if ($line ne '') {
+                                    $repo_enabled = 1;
+                                }
+                            }
+                        }
+                    }
+                    if ($repo_enabled) {
+                        if (open(my $pipe, '-|',"zypper ref && zypper in -l -n $packagelist")) {
+                            while (my $line = <$pipe>) {
+                                print $line;
+                            }
+                            close($pipe);
+                        }
+                    }
+                }
+            } elsif ($dist =~ /^(fedora|alma|rocky|centos|oracle|rhes|scientific)$/) {
+                if ($dist ne 'fedora') {
+                    if (($version < 10) && ($version > 7)) {
+                        my $module_enabled;
+                        if (open(my $pipe, '-|',"dnf module list nodejs --enabled 2>/dev/null")) {
+                            while (my $line = <$pipe>) {
+                                if ($line =~ /\Q24 [e]\E/) {
+                                    $module_enabled = 1;
+                                    last;
+                                }
+                            }
+                            close($pipe);
+                        }
+                        unless ($module_enabled) {
+                            if (open(my $pipe, '-|','dnf module reset nodejs -y 2>/dev/null')) {
+                                while (my $line = <$pipe>) {
+                                    print $line;
+                                }
+                                close($pipe);
+                            }
+                            if (open(my $pipe, '-|','dnf module enable nodejs:24 -y 2>/dev/null')) {
+                                while (my $line = <$pipe>) {
+                                    print $line;
+                                }
+                                close($pipe);
+                            }
+                            if (open(my $pipe, '-|','dnf module list nodejs --enabled 2>/dev/null')) {
+                                while (my $line = <$pipe>) {
+                                    print $line;
+                                    if ($line =~ /\Q24 [e]\E/) {
+                                        $module_enabled = 1;
+                                        last;
+                                    }
+                                }
+                                close($pipe);
+                            }
+                        }
+                        unless ($module_enabled) {
+                            @packages = ();
+                            undef($packagelist);
+                            print "Could not enable nodejs:24 module.\n"
+                        }
+                    }
+                }
+                if (@packages) {
+                    if (($dist eq 'fedora') || ($version > 7)) {
+                        if (open(my $pipe, '-|',"dnf install $packagelist -y")) {
+                            while (my $line = <$pipe>) {
+                                print $line;
+                            }
+                            close($pipe);
+                        }
+                    } elsif ($version == 7) {
+                        my $command = 'yum';
+                        #FIXME use node-v24.19.0-lts from https://github.com/sbwml/node-latest-centos/releases
+                    }
+                }
+            }
+        }
+        if (($browser ne '') && ($axeinstall{$browser})) {
+            print "Installing browser: $browser\n";
+            if ($dist =~ /^(ubuntu|debian)$/) {
+                my $browser_deb;
+                if ($dist eq 'debian') {
+                    $browser_deb = 'chromium';
+                } else {
+                    if ($browser eq '/usr/bin/google-chrome-stable') {
+                        $browser_deb = 'google-chrome-stable';
+                    } elsif ($browser eq '/usr/bin/chromium') {
+                        $browser_deb = 'chromium-browser'; 
+                    }
+                }
+                if ($browser_deb) {
+                    if (open(my $pipe, '-|',"apt-get -y install $browser_deb")) {
+                        while (my $line = <$pipe>) {
+                            print $line;
+                        }
+                        close($pipe);
+                    }
+                }
+            } elsif ($dist eq 'fedora') {
+                my $browser_rpm;
+                if ($browser eq '/usr/bin/chromium-browser') {
+                    $browser_rpm = 'chromium';
+                }
+                if ($browser_rpm) {
+                    if (open(my $pipe, '-|',"dnf install $browser_rpm -y")) {
+                        while (my $line = <$pipe>) {
+                            print $line;
+                        }
+                        close($pipe);
+                    }
+                }
+            } elsif ($dist =~ /^(alma|rocky|centos|oracle|rhes|scientific|centos-stream)$/) {
+                my $command;
+                if ($version > 7) {
+                    $command = 'dnf';
+                } elsif ($version == 7) {
+                    $command = 'yum'; 
+                }
+                if ($command ne '') {
+                    my $browser_rpm;
+                    if ($browser eq '/usr/bin/chromium-browser') {
+                        $browser_rpm = 'chromium';
+                    } elsif ($browser eq '/usr/bin/firefox') {
+                        $browser_rpm = 'firefox';
+                    }
+                    if ($browser_rpm) {
+                        if (open(my $pipe, '-|',"dnf install $browser_rpm -y")) {
+                            while (my $line = <$pipe>) {
+                                print $line;
+                            }
+                            close($pipe);
+                        }
+                    }
+                }
+            } elsif ($dist eq 'sles') {
+                my ($addrepo,$repo_enabled);
+                if ($version > 12) {
+                    if (open(my $pipe, '-|',"zypper lr -E | grep -i packagehub")) {
+                        my $line = <$pipe>;
+                        close($pipe);
+                        chomp($line);
+                        if ($line eq '') {
+                            $addrepo = 1;
+                        } else {
+                            $repo_enabled = 1;
+                        }
+                    }
+                    if ($addrepo) {
+                        if (($slesversion ne '') && ($arch ne '')) {
+                            if (open(my $pipe, '-|',"SUSEConnect -p PackageHub/$slesversion/$arch")) {
+                                while (my $line = <$pipe>) {
+                                    print $line;
+                                }
+                                close($pipe);
+                            }
+                            if (open(my $pipe, '-|',"zypper lr -E | grep -i packagehub")) {
+                                my $line = <$pipe>;
+                                close($pipe);
+                                chomp($line);
+                                if ($line ne '') {
+                                    $repo_enabled = 1;
+                                }
+                            }
+                        }
+                    }
+                } elsif ($version == 12) {
+                    $repo_enabled = 1;
+                }
+                if ($repo_enabled) {
+                    my $browser_rpm;
+                    if ($browser eq '/usr/bin/chromium-browser') {
+                        $browser_rpm = 'chromium';
+                    } elsif ($browser eq '/usr/bin/firefox') {
+                        $browser_rpm = 'MozillaFirefox';
+                    }
+                    if ($browser_rpm) {
+                        if (open(my $pipe, '-|',"zypper ref && zypper in -l -n $browser_rpm")) {
+                            while (my $line = <$pipe>) {
+                                print $line;
+                            }
+                            close($pipe);
+                        }
+                    }
+                }
+            }
+        }
+    }
 </perlscript>
 </file>
 <file>


More information about the LON-CAPA-cvs mailing list