Annotation of loncom/debugging_tools/unsubresources.pl, revision 1.2

1.1       raeburn     1: #!/usr/bin/perl
                      2: #
                      3: # The LearningOnline Network
                      4: #
                      5: # When an access node is being taken offline either permanently
                      6: # or for a long period of time, it would be friendly to domains
                      7: # which have library nodes from which resources have been replicated
                      8: # to unsubscribe from the resources, to avoid accumulation of
                      9: # delayed "update" transactions in lonnet.perm.log on the library
                     10: # nodes which are the home servers for the authors of the replicated
                     11: # resources, in the event that the author publishes updated version(s).
                     12: #
1.2     ! raeburn    13: # $Id: unsubresources.pl,v 1.1 2020/05/13 01:49:55 raeburn Exp $
1.1       raeburn    14: #
                     15: # Copyright Michigan State University Board of Trustees
                     16: #
                     17: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                     18: #
                     19: # LON-CAPA is free software; you can redistribute it and/or modify
                     20: # it under the terms of the GNU General Public License as published by
                     21: # the Free Software Foundation; either version 2 of the License, or
                     22: # (at your option) any later version.
                     23: #
                     24: # LON-CAPA is distributed in the hope that it will be useful,
                     25: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     26: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     27: # GNU General Public License for more details.
                     28: #
                     29: # You should have received a copy of the GNU General Public License
                     30: # along with LON-CAPA; if not, write to the Free Software
                     31: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     32: #
                     33: # /home/httpd/html/adm/gpl.txt
                     34: #
                     35: # http://www.lon-capa.org/
                     36: #
                     37: #################################################
                     38: 
                     39: use strict;
                     40: use lib '/home/httpd/lib/perl/';
                     41: use LONCAPA::Configuration;
                     42: use LONCAPA qw(:DEFAULT :match);
                     43: use Apache::lonlocal;
                     44: use Apache::lonnet;
                     45: 
                     46: my ($londocroot,$londaemons);
                     47: 
                     48: BEGIN {
                     49:     my $perlvar=&LONCAPA::Configuration::read_conf();
                     50:     if (ref($perlvar) eq 'HASH') {
                     51:         $londocroot = $perlvar->{'lonDocRoot'};
                     52:         $londaemons = $perlvar->{'lonDaemons'};
                     53:     }
                     54:     undef($perlvar);
                     55: }
                     56: 
                     57: my $lang = &Apache::lonlocal::choose_language();
                     58: &Apache::lonlocal::get_language_handle(undef,$lang);
                     59: 
                     60: my $parameter=$ARGV[0];
                     61: $parameter =~ s/^\s+//;
                     62: $parameter =~ s/\s+$//;
                     63: 
                     64: if ((@ARGV > 1) || (($parameter ne '') && ($parameter ne 'execute'))) {
                     65:     print &mt('usage: [_1]','unsubresources.pl [dryrun|execute]')."\n\n".
                     66:           &mt('You should enter either no arguments, or just one argument: execute.')."\n".
                     67:           &mt("execute - to unlink resources in [_1], and send unsub request to homeserver of resource author",
                     68:               "$londocroot/res/'")."\n".
                     69:           &mt('no argument to do a dry run, without actually unlinking or unsubscribing anything.')."\n";
                     70:     exit;
                     71: }
                     72: 
                     73: my $wwwid=getpwnam('www');
                     74: if ($wwwid!=$<) {
                     75:     print &mt('This must be run as user www in order to unsubscribe previously subscribed resources.')."\n".
                     76:           &mt('Stopping')."\n";
                     77:     exit;
                     78: }
                     79: 
                     80: if ($londocroot eq '') {
                     81:     print &mt('Could not determine location of [_1] directory.',"'lonDocRoot'")."\n".
                     82:           &mt('Stopping')."\n";
                     83:     exit;
                     84: }
                     85: if ($londaemons eq '') {
                     86:     print &mt('Could not determine location of [_1] directory.',"'lonDaemons'")."\n".
                     87:           &mt('Stopping')."\n";
                     88:     exit;
                     89: }
                     90: 
                     91: # Get machine IDs
                     92: my @ids=&Apache::lonnet::current_machine_ids();
                     93: 
                     94: print "\n".&mt("Unlinking and unsubscribing resources in $londocroot/res/")."\n".
                     95:       &mt('No changes will occur for resources for which this server is the homeserver of the author of the resource.')."\n".
                     96:       "-----------------------------\n\n".
                     97:       &mt('If run without an argument, the script will report what it would do when unlinking and unsubscribing resources in [_1].',
                     98:           "'$londocroot/res/'")."\n\n";
                     99: 
                    100: my ($action) = ($parameter=~/^(execute)$/);
                    101: if ($action eq '') {
                    102:     $action = 'dryrun';
                    103: }
                    104: 
                    105: if ($action eq 'dryrun') {
                    106:     print "\n".
                    107:           &mt('Running in exploratory mode ...')."\n\n".
                    108:           &mt('Run with argument [_1] to actually unlink and unsubscribe resources in [_2], i.e., [_3]',
                    109:               "'execute'","'$londocroot/res/'","\n\nperl unsubresources.pl execute")."\n\n\n".
                    110:           &mt('Continue? ~[y/N~] ');
                    111:     if (!&get_user_selection()) {
                    112:         exit;
                    113:     } else {
                    114:         print "\n";
                    115:     }
                    116: } else {
                    117:     print "\n *** ".&mt('Running in a mode where changes will be made.')." ***\n";
                    118:     print "\n".
                    119:           &mt('Mode is [_1] -- replicated resources in [_2] will be unlinked and unsubscribed.',
1.2     ! raeburn   120:               "'$action'","'$londocroot/res/'")."\n".
        !           121:           &mt('Results will be logged in [_1].',"$londaemons/logs/unsubresources.log")."\n";
1.1       raeburn   122:     print &mt('Continue? ~[y/N~] ');
                    123:     if (!&get_user_selection()) {
                    124:         exit;
                    125:     } else {
                    126:         print "\n";
                    127:     }
                    128: }
                    129: 
                    130: my $dir = "$londocroot/res";
                    131: my %alreadyseen;
                    132: 
                    133: my $logfh;
                    134: unless ($action eq 'dryrun') {
                    135:     if (!open($logfh,'>>',"$londaemons/logs/unsubresources.log")) {
                    136:         print &mt('Could not open log file: [_1] for writing.',
                    137:                   "'$londaemons/logs/unsubresources.log'")."\n".
                    138:               &mt('Stopping.')."\n";
                    139:         exit;
                    140:     } else {
                    141:         &start_logging($logfh,$action);
                    142:     }
                    143: }
                    144: &check_directory($action,$dir,$logfh,\@ids,\%alreadyseen);
                    145: unless ($action eq 'dryrun') {
                    146:     &stop_logging($logfh);
                    147: }
                    148: print "\n".&mt('Done')."\n";
                    149: exit;
                    150: 
                    151: sub check_directory {
                    152:     my ($action,$dir,$fh,$idsref,$seenref,$currhome) = @_;
                    153:     my $msg;
                    154:     if (opendir(my $dirh,$dir)) {
                    155:         while (my $item=readdir($dirh)) {
                    156:             next if ($item =~ /^\./);
                    157:             if (-d "$dir/$item") {
                    158:                 if ($dir eq "$londocroot/res") {
                    159:                     next if (($item eq 'adm') || ($item eq 'lib') || ($item eq 'res'));
                    160:                     if (&Apache::lonnet::domain($item) ne '') {
                    161:                         my %servers = &Apache::lonnet::get_unique_servers($item);
                    162:                         my @libservers;
                    163:                         foreach my $server (keys(%servers)) {
                    164:                             if (&Apache::lonnet::is_library($server)) {
                    165:                                 push(@libservers,$server); 
                    166:                             }
                    167:                         }
                    168:                         if (@libservers == 1) {
                    169:                             if ((ref($idsref) eq 'ARRAY') && (grep(/^\Q$libservers[0]\E$/,@{$idsref}))) {
                    170:                                 $msg = &mt('Skipping directory for [_1] as [_2] is the single library node for the domain',
                    171:                                            $item,$libservers[0])."\n";
                    172:                                 if ($action eq 'execute') {
                    173:                                     print $fh $msg;
                    174:                                 } else {
                    175:                                     print $msg;
                    176:                                 }
                    177:                                 next;
                    178:                             }
                    179:                         }
                    180:                         &check_directory($action,"$dir/$item",$fh,$idsref,$seenref);
                    181:                     } else {
                    182:                         $msg = &mt('Domain [_1] in [_2] is unavailable',
                    183:                                    $item,$dir)."\n";
                    184:                         if ($action eq 'execute') {
                    185:                             print $fh $msg;
                    186:                         } else {
                    187:                             print $msg;
                    188:                         }
                    189:                         next;
                    190:                     }
                    191:                 } elsif ($dir =~ m{^\Q$londocroot/res\E/($match_domain)$}) {
                    192:                     my $udom = $1;
                    193:                     if ($item =~ /^($match_username)$/) {
                    194:                         my $uname = $1;
                    195:                         $currhome = &Apache::lonnet::homeserver($uname,$udom,1);
                    196:                         if ($currhome eq 'no_host') {
                    197:                             $msg = &mt('No homeserver for user: [_1] domain: [_2]',
                    198:                                        $uname,$udom)."\n";
                    199:                             if ($action eq 'execute') {
                    200:                                 print $fh $msg;
                    201:                             } else {
                    202:                                 print $msg;
                    203:                             }
                    204:                         } elsif ((ref($idsref) eq 'ARRAY') && (grep(/^\Q$currhome\E$/,@{$idsref}))) {
                    205:                             $msg = &mt("Skipping user: [_1] in domain: [_2] as this is the user's homeserver.",
                    206:                                        $uname,$udom)."\n"; 
                    207:                             if ($action eq 'execute') {
                    208:                                 print $fh $msg;
                    209:                             } else {
                    210:                                 print $msg;
                    211:                             }
                    212:                         } else {
                    213:                             &check_directory($action,"$dir/$item",$fh,$idsref,$seenref,$currhome);
                    214:                         }
                    215:                     } else {
                    216:                         $msg = &mt('Username: [_1] in domain: [_2] is invalid',
                    217:                                    $item,$udom)."\n";
                    218:                         if ($action eq 'execute') {
                    219:                             print $fh $msg;
                    220:                         } else {
                    221:                             print $msg;
                    222:                         }
                    223:                     }
                    224:                 } else {
                    225:                     &check_directory($action,"$dir/$item",$fh,$idsref,$seenref,$currhome);
                    226:                 }
                    227:             } elsif (-f "$dir/$item") {
                    228:                 if ($dir =~ m{^\Q$londocroot/res\E/$match_domain/$match_username}) {
                    229:                     next if ($seenref->{"$dir/$item"});
                    230:                     if ($action eq 'execute') {
                    231:                         if (unlink("$dir/$item")) {
                    232:                             if ($item =~ /\.meta$/) {
                    233:                                 my $nonmeta = $item;
                    234:                                 $nonmeta =~ s/\.meta$//;
                    235:                                 next if ((-e "$dir/$nonmeta") || ($seenref->{"$dir/$nonmeta"}));
                    236:                             } elsif (-e "$dir/$item.meta") {
                    237:                                 unlink("$dir/$item.meta");
                    238:                             }
                    239:                             if ($currhome ne '') {
1.2     ! raeburn   240:                                 my $result = &Apache::lonnet::unsubscribe("$dir/$item");
1.1       raeburn   241:                                 if ($result eq 'ok') {
                    242:                                     print $fh &mt('Unsub complete for [_1] at [_2]',
                    243:                                                      "$dir/$item",$currhome)."\n";
                    244:                                 } else {
                    245:                                     print $fh &mt('Result of unsub for [_1] at [_2] was: [_3]',
                    246:                                                      "$dir/$item",$currhome,$result)."\n";
                    247:                                 }
                    248:                             }
                    249:                             $seenref->{"$dir/$item"} = 1;
                    250:                         } else {
                    251:                             print $fh &mt('Failed to unlink [_1]',"$dir/$item")."\n"; 
                    252:                         }
                    253:                     } else {
                    254:                         if ($item =~ /\.meta$/) {
                    255:                             my $nonmeta = $item;
                    256:                             $nonmeta =~ s/\.meta$//;
                    257:                             next if (-e "$dir/$nonmeta");
                    258:                             print &mt('Would unlink [_1] and send unsub to [_2]',
                    259:                                       "$dir/$item",$currhome)."\n";
                    260:                         } elsif (-e "$dir/$item.meta") {
                    261:                             print &mt('Would unlink [_1] and [_2], and send unsub to [_3]',
                    262:                                       "$dir/$item","$dir/$item.meta",$currhome)."\n";
                    263:                             $seenref->{"$dir/$item.meta"} = 1;
                    264:                         } else {
                    265:                             print &mt('Would unlink [_1] and send unsub to [_2]',
                    266:                                       "$dir/$item",$currhome)."\n";
                    267:                         }
                    268:                         $seenref->{"$dir/$item"} = 1;
                    269:                     }
                    270:                 } else {
                    271:                     $msg = &mt('Invalid directory [_1]',$dir)."\n";
                    272:                     if ($action eq 'execute') {
                    273:                         print $fh $msg;
                    274:                     } else {
                    275:                         print $msg;
                    276:                     }
                    277:                 }
                    278:             }
                    279:         }
                    280:         closedir($dirh);
                    281:     } else {
                    282:         $msg = &mt('Could not open directory: [_1]',$dir)."\n";
                    283:         if ($action eq 'execute') {
                    284:             print $fh $msg;
                    285:         } else {
                    286:             print $msg;
                    287:         }
                    288:     }
                    289:     return;
                    290: }
                    291: 
                    292: sub get_user_selection {
                    293:     my ($defaultrun) = @_;
                    294:     my $do_action = 0;
                    295:     my $choice = <STDIN>;
                    296:     chomp($choice);
                    297:     $choice =~ s/(^\s+|\s+$)//g;
                    298:     my $yes = &mt('y');
                    299:     if ($defaultrun) {
                    300:         if (($choice eq '') || ($choice =~ /^\Q$yes\E/i)) {
                    301:             $do_action = 1;
                    302:         }
                    303:     } else {
                    304:         if ($choice =~ /^\Q$yes\E/i) {
                    305:             $do_action = 1;
                    306:         }
                    307:     }
                    308:     return $do_action;
                    309: }
                    310: 
                    311: sub start_logging {
                    312:     my ($fh,$action) = @_;
                    313:     my $start = localtime(time);
                    314:     print $fh "*****************************************************\n".
                    315:               &mt('[_1] - mode is [_2].',
                    316:                   'unsubresources.pl',"'$action'")."\n".
                    317:               &mt('Started -- time: [_1]',$start)."\n".
                    318:               "*****************************************************\n\n";
                    319:     return;
                    320: }
                    321: 
                    322: sub stop_logging {
                    323:     my ($fh) = @_;
                    324:     my $end = localtime(time);
                    325:     print $fh "*****************************************************\n".
                    326:                &mt('Ended -- time: [_1]',$end)."\n".
                    327:               "*****************************************************\n\n\n";
                    328:     close($fh);
                    329:     return;
                    330: }

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