File:  [LON-CAPA] / loncom / cgi / takeoffline.pl
Revision 1.8: download - view: text, annotated - select for diffs
Wed Jan 21 15:12:03 2015 UTC (9 years, 2 months ago) by raeburn
Branches: MAIN
CVS tags: version_2_12_X, HEAD
- Bug 6767
  - In case where a specific destination is chosen when server is "offline"
    the destination in the meta refresh needs to be the hostname not the
    destination server's lonhostID.
- xhtml now satisfies w3c validation
- eliminate deprecated <font> tags.

#!/usr/bin/perl
$|=1;
# Take machine offline, reroute traffic
#
# $Id: takeoffline.pl,v 1.8 2015/01/21 15:12:03 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#

use strict;
use lib '/home/httpd/lib/perl/';
use Apache::lonlocal;
use Apache::loncommon;
use Apache::lonnet;
use LONCAPA::loncgi;
use LONCAPA::lonauthcgi;

print "Content-type: text/html\n\n";

&main();

sub main {
    if (!&LONCAPA::lonauthcgi::check_ipbased_access('takeoffline')) {
        if (!&LONCAPA::loncgi::check_cookie_and_load_env()) {
            &Apache::lonlocal::get_language_handle();
            print(&LONCAPA::loncgi::missing_cookie_msg());
            return;
        }

        if (!&LONCAPA::lonauthcgi::can_view('takeoffline')) {
            &Apache::lonlocal::get_language_handle();
            print(&LONCAPA::lonauthcgi::unauthorized_msg('takeoffline'));
            return;
        }
    }
    &Apache::lonlocal::get_language_handle();

    if ($ENV{'QUERY_STRING'} =~ /^phase\=two\&?(.*)$/) {
        my $reroute = $1;
        print &Apache::loncommon::start_page('Take Offline');
        &phasetwo($reroute);
    } else {
        my $js = <<ENDJS;
<script type="text/javascript">
// <![CDATA[

function setphase(form) {
    var subaction = '/cgi-bin/takeoffline.pl?phase=two';
    form.action = subaction+'&'+form.rerouteto.options[form.rerouteto.selectedIndex].value;
    form.submit();
}

// ]]>
</script>
ENDJS
        print &Apache::loncommon::start_page('Take Offline',$js);
        &phaseone();
    }
    print &Apache::loncommon::end_page();
    return;
}

sub phaseone {
    print '<h2>'.&Apache::lonlocal::mt('Take Offline').'</h2>';
    my ($is_dc,@okmachines,%servers);
    my @poss_domains = &Apache::lonnet::current_machine_domains();
    foreach my $dom (@poss_domains) {
        if ($Apache::lonnet::env{'request.role'} eq "dc./$dom/") {
            $is_dc = 1;
        }
        my %domconfig = &Apache::lonnet::get_dom('configuration',['serverstatuses'],$dom);
        if (ref($domconfig{'serverstatuses'}) eq 'HASH') {
            if (ref($domconfig{'serverstatuses'}{'takeonline'}) eq 'HASH') {
                if ($domconfig{'serverstatuses'}{'takeonline'}{'machines'} ne '') {
                    @okmachines = split(/,/,$domconfig{'serverstatuses'}{'takeonline'}{'machines'});
                }
            }
        }
        %{$servers{$dom}} = &Apache::lonnet::get_servers($dom);
    }
    my $ip = $ENV{'REMOTE_ADDR'};
    my $lonhost = $Apache::lonnet::perlvar{'lonHostID'};
    print '<p>'.&mt("When a LON-CAPA server is 'taken offline' using this utility, the standard log-in page will be replaced with one of the following:").'</p>'.
          '<ul><li>'.&mt('A page which automatically performs a redirect to another server in your domain - the server must be specified below.').'</li>'.
              '<li>'.&mt('A page which announces that this LON-CAPA server is offline.').'</li></ul>';
    print '<p>'.&mt("Once a server is offline, the [_1]'take online'[_2] utility can be used to reverse this, but you should verify that you will still be able to access that script once the server is in an offline state.",'<a href="/cgi-bin/takeonline.pl">','</a>').'</p>';
    print '<p>'.&mt("In common with other Domain Status pages the 'take online' script is accessible from certain IP addresses:").'</p><ul>'.
          '<li>'.&mt('The loopback device - 127.0.0.1 (localhost) - for times when you are web browsing from the server itself.').'</li>'.
          '<li>'.&mt("Specified IP addresses set via the configuration for [_1]Access to Server Status Pages[_2] for domain(s) hosted on the server.",'<a href="/adm/domainprefs?phase=display&amp;actions=serverstatuses">','</a>').'</li></ul><p>'.
          &mt("Once the server is offline you will not be able to log-in directly to select a Domain Coordinator role to use the 'Take online' script, unless IP-based controls provide your access.").'<br />'.&mt("However, you will be able to log-in to a different server in the LON-CAPA network, select a Domain Coordinator role in this server's domain, and then use: [_1] to migrate you session to this machine.","<br /><tt>/adm/switchserver?otherserver=$lonhost</tt>").'<br /></p><hr />';
    if ($ip eq '127.0.0.1') {
        print '<div class="LC_info">'.&mt('You are accessing this page from the loopback device.').'</div>';
    } elsif (!@okmachines) {
        print '<div class="LC_warning">'.&mt("IP-based access to the 'take online' page is currently unavailable, as no IP addresses have been specified.").'</div>';
    } elsif (!grep(/^\Q$ip\E$/,@okmachines)) {
        print '<div class="LC_warning">'.&mt("Your current IP [_1] is not among those configured to have IP-based access to the 'take online' utility.",$ip).'</div>';
    } else {
        print '<div class="LC_info">'.&mt("Your current IP [_1] is configured to have IP-based access to the 'take online' utility.",$ip).'</div>';
    }
    my (%allhosts,$otherserver,$domain);
    if ($ENV{'QUERY_STRING'}) {
        ($otherserver,$domain)=split(/\&/,$ENV{'QUERY_STRING'});
    }
    print '<hr /><form method="post" name="takeoffline" onsubmit="javascript:setphase(this);" action="">';

    my $options;
    if ($domain) {
        if (grep(/^\Q$domain\E$/,keys(%servers))) {
            if (ref($servers{$domain}) eq 'HASH') {
                foreach my $hostid (sort(keys(%{$servers{$domain}}))) {
                    next if ($hostid eq $lonhost);
                    my $selchk = '';
                    if ($otherserver eq $hostid) {
                        $selchk = ' selected="selected"';
                    }
                    $options .=
                        "<option value=\"$hostid&amp;$domain\"$selchk>$servers{$domain}{$hostid}</option>\n";
                }
            }
        }
    }
    foreach my $dom (sort(keys(%servers))) {
        next if (($domain) && ($dom eq $domain));
        if (ref($servers{$dom}) eq 'HASH') {
            foreach my $hostid (sort(keys(%{$servers{$dom}}))) {
                next if ($hostid eq $lonhost);
                next if(defined($allhosts{$hostid}));
                $allhosts{$hostid} = 1;
                my $selchk = '';
                if ($otherserver eq $hostid) {
                    $selchk = ' selected="selected"';
                }
                $options .=
                    "<option value=\"$hostid&amp;$dom\"$selchk>$servers{$dom}{$hostid}</option>\n";
            }
        }
    }
    if ($options) {
        print &mt('Optional: choose another server in your domain, to which to redirect log-ins: ').
              '<select name="rerouteto">'."\n".
              ' <option value="">'.&mt('Please select').'</option>'."\n".
              $options.'</select>'."\n";
    } else {
        print &mt('There are no other servers in your domain to which to redirect logins.');
    }
    print '<br /><br /><input type="submit" name="offline" value="Take Offline" />'."\n".
          '</form>'."\n";
}

sub phasetwo {
    my ($reroute) = @_;
    print '<h2>'.&Apache::lonlocal::mt('Take Offline').'</h2>';
    my $statusmsg;
    if ($reroute ne '') {
        my ($otherserver,$domain)=split(/\&/,$reroute);
        my $otherhostname = &reroute($otherserver,$domain);
        if ($otherhostname ne '') {
            print &Apache::lonlocal::mt('Rerouting to [_1]',$otherhostname);
            $statusmsg = "status=rerouting&server=$otherserver&domain=$domain&time=".time.
                         "by=$Apache::lonnet::env{'user.name'}:$Apache::lonnet::env{'user.domain'}";
        }
    } else {
        if (&dead()) {
            print &Apache::lonlocal::mt('No reroute server given, taking completely offline.');
            $statusmsg = 'status=offline&time='.time."by=$Apache::lonnet::env{'user.name'}:$Apache::lonnet::env{'user.domain'}"
        }
    }
    if ($statusmsg) {
        if (open (STATUS,'>/home/httpd/html/lon-status/reroute.txt')) {
            print STATUS "$statusmsg\n";
            close(STATUS);
        } else {
            print &Apache::lonlocal::mt('Logging of status change to [_1] failed.','<tt>/home/httpd/html/lon-status/reroute.txt</tt>'); 
        }
    }
}

sub dead {
    if (open (OUT,'>/home/httpd/html/index.html')) {
        print OUT &Apache::lonlocal::mt('This LON-CAPA server is currently offline.');
        close(OUT);
        return 'ok';
    }
    return;
}

sub reroute {
    my ($otherserver,$domain) = @_;
    my $otherhostname = &Apache::lonnet::hostname($otherserver);
    my $protocol = $Apache::lonnet::protocol{$otherserver};
    $protocol = 'http' if ($protocol ne 'https');
    if ($otherhostname ne '') {
        if (open (OUT,'>/home/httpd/html/index.html')) {
            print OUT (<<ENDNEWINDEX);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>Welcome to the LearningOnline Network with CAPA</title>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta http-equiv="refresh" content="0.5; url=$protocol://$otherhostname/adm/login?domain=$domain">
  <meta http-equiv="pragma" content="no-cache" />
 </head>
 <body style="background-color:#004400; margin: 0px;">
  <img src="/adm/lonIcons/header.gif" alt="loncapa banner" />
<p style="color:#ffffff">Connecting to 
<a href="$protocol://$otherhostname/adm/login?domain=$domain" style="color:#ffffff">$protocol://$otherhostname/</a></p>
</body>
</html>
ENDNEWINDEX
           close(OUT);
           return $otherhostname;
        }
    }
    return;
}

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