Annotation of loncom/debugging_tools/modify_config_files.pl, revision 1.8

1.1       matthew     1: #!/usr/bin/perl -w
                      2: #
                      3: # The LearningOnline Network
                      4: #
1.8     ! raeburn     5: # $Id: modify_config_files.pl,v 1.7 2007/04/24 13:09:40 raeburn Exp $
1.1       matthew     6: #
                      7: # Copyright Michigan State University Board of Trustees
                      8: #
                      9: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                     10: #
                     11: # LON-CAPA is free software; you can redistribute it and/or modify
                     12: # it under the terms of the GNU General Public License as published by
                     13: # the Free Software Foundation; either version 2 of the License, or
                     14: # (at your option) any later version.
                     15: #
                     16: # LON-CAPA is distributed in the hope that it will be useful,
                     17: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     18: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     19: # GNU General Public License for more details.
                     20: #
                     21: # You should have received a copy of the GNU General Public License
                     22: # along with LON-CAPA; if not, write to the Free Software
                     23: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     24: #
                     25: # /home/httpd/html/adm/gpl.txt
                     26: #
                     27: # http://www.lon-capa.org/
                     28: #
                     29: ###
                     30: 
                     31: =pod
                     32: 
                     33: =head1 NAME
                     34: 
                     35: B<modify_config_files.pl>
                     36: 
                     37: =head1 SYNOPSIS
                     38: 
                     39: This script modifies /etc/yum.conf and /etc/my.cnf.
                     40: 
                     41: =head1 DESCRIPTION
                     42: 
                     43: This script modifies /etc/yum.conf and /etc/my.cnf to ensure certain parameters
                     44: are set properly.  The LON-CAPA yum repositories are added to /etc/yum.conf.
                     45: The /etc/my.cnf file is modified to set the wait_timeout to 1 year.  Backup
                     46: copies of each file are made in /etc.
                     47: 
                     48: =cut
                     49: 
                     50: use strict;
                     51: use File::Copy;
1.3       matthew    52: use lib '/home/httpd/lib/perl/';
                     53: use LONCAPA::Configuration;
                     54: my $loncapa_config=LONCAPA::Configuration::read_conf('loncapa.conf');
1.1       matthew    55: 
1.6       raeburn    56: open(DSH,"$$loncapa_config{'lonDaemons'}/distprobe |");
                     57: my $dist = <DSH>;
                     58: chomp($dist);
                     59: close(DSH);
                     60: 
                     61: my $yum_status;
                     62: if ($dist =~ /^fedora\d+$/) {
                     63:     $yum_status =  
                     64:         &update_file('/etc/yum.conf',
                     65:              [{section => 'loncapa-updates-$basearch',
1.1       matthew    66:                key     => 'name=',
1.6       raeburn    67:                value   => 'Fedora Core $releasever LON-CAPA $basearch Updates',
                     68:            }, {section => 'loncapa-updates-$basearch',
1.1       matthew    69:                key     => 'baseurl=',
                     70:                value   => 'http://install.loncapa.org/fedora/linux/loncapa/'.
1.6       raeburn    71:                    '$releasever/$basearch',
                     72:            }, {section => 'loncapa-updates-$basearch',
1.5       matthew    73:                key     => 'gpgcheck=',
                     74:                value   => '0',
1.1       matthew    75:            }, {section => 'loncapa-updates-noarch',
                     76:                key     => 'name=',
                     77:                value   => 'Fedora Core $releasever LON-CAPA noarch Updates',
                     78:            }, {section => 'loncapa-updates-noarch',
                     79:                key     => 'baseurl=',
                     80:                value   => 'http://install.loncapa.org/fedora/linux/loncapa/'.
                     81:                    '$releasever/noarch',
1.5       matthew    82:            }, {section => 'loncapa-updates-noarch',
                     83:                key     => 'gpgcheck=',
                     84:                value   => '0',
1.1       matthew    85:            }]);
1.6       raeburn    86: } elsif ($dist =~ /^rhes(\d+)$/) {
                     87:     if ($1 > 4) {
                     88:         $yum_status =
                     89:             &update_file('/etc/yum.conf',
                     90:                  [{section => 'loncapa-updates-$basearch',
                     91:                    key     => 'name=',
                     92:                    value   => 'RHEL $releasever LON-CAPA $basearch Updates',
                     93:                }, {section => 'loncapa-updates-$basearch',
                     94:                    key     => 'baseurl=',
1.8     ! raeburn    95:                    value   => 'http://install.loncapa.org/redhat/linux/enterprise/loncapa/'.
1.6       raeburn    96:                        '$releasever/$basearch',
                     97:                }, {section => 'loncapa-updates-$basearch',
                     98:                    key     => 'gpgcheck=',
                     99:                    value   => '1',
                    100:                }, {section => 'loncapa-updates-$basearch',
                    101:                    key     => 'gpgkey=',
                    102:                    value   => 'http://install.loncapa.org/versions/redhat/'.
1.7       raeburn   103:                               'RPM-GPG-KEY-loncapa',
1.6       raeburn   104:                }, {section => 'loncapa-updates-noarch',
                    105:                    key     => 'name=',
                    106:                    value   => 'RHEL $releasever LON-CAPA noarch Updates',
                    107:                }, {section => 'loncapa-updates-noarch',
                    108:                    key     => 'baseurl=',
1.8     ! raeburn   109:                    value   => 'http://install.loncapa.org/redhat/linux/enterprise/loncapa/'.
1.6       raeburn   110:                        '$releasever/noarch',
                    111:                }, {section => 'loncapa-updates-noarch',
                    112:                    key     => 'gpgcheck=',
                    113:                    value   => '1',
                    114:                }, {section => 'loncapa-updates-noarch',
                    115:                    key     => 'gpgkey=',
                    116:                    value   => 'http://install.loncapa.org/versions/redhat/'.
1.7       raeburn   117:                               'RPM-GPG-KEY-loncapa',
1.6       raeburn   118:                }]);
                    119:     }
                    120: }
1.1       matthew   121: 
1.4       matthew   122: my $mysql_global_status =
                    123:     &update_file('/etc/my.cnf',
1.1       matthew   124:              [{section =>'mysqld',
                    125:                key     =>'set-variable=wait_timeout=',
                    126:                value   =>'31536000', }]);
                    127: 
1.3       matthew   128: my $local_my_cnf = '/home/www/.my.cnf';
                    129: if (! -e $local_my_cnf) {
1.4       matthew   130:     # Create a file so we can do something with it...
1.3       matthew   131:     system("touch $local_my_cnf");
                    132: }
1.4       matthew   133: my $mysql_www_status =
                    134:     &update_file($local_my_cnf,
1.3       matthew   135:              [{section =>'client',
                    136:                key     =>'user=',
                    137:                value   =>'www',},
                    138:               {section =>'client',
                    139:                key     =>'password=',
                    140:                value   =>$loncapa_config->{'lonSqlAccess'}},]);
                    141: 
1.4       matthew   142: my $exitvalue = 0;
                    143: 
                    144: if ($mysql_global_status) { $exitvalue = 1; }
                    145: 
                    146: exit $exitvalue;
1.1       matthew   147: 
                    148: 
                    149: 
                    150: #################################################################
                    151: #################################################################
                    152: 
                    153: =pod
                    154: 
                    155: =over 4
                    156: 
                    157: =cut
                    158: 
                    159: #################################################################
                    160: #################################################################
                    161: sub update_file {
                    162:     my ($file,$newdata) = @_;
                    163:     return 1 if (! -e $file);
                    164:     my $backup = $file.'.backup';
                    165:     if (! copy($file,$backup)) {
1.4       matthew   166:         warn "**** Error: Unable to make backup of $file";
1.1       matthew   167:         return 0;
                    168:     }
                    169:     my ($filedata) = &parse_config_file($file);
1.4       matthew   170:     if (! ref($filedata)) { warn "**** Error: $filedata"; return 0;}
                    171:     my $modified = 0;
1.1       matthew   172:     foreach my $data (@$newdata) {
                    173:         my $section = $data->{'section'};
                    174:         my $key = $data->{'key'};
                    175:         my $value = $data->{'value'};
1.4       matthew   176:         my $result = &modify_config_file($filedata,$section,$key,$value);
                    177:         if ($result) { $modified = 1; }
                    178:     }
                    179:     if ($modified) {
                    180:         my $result = &write_config_file($file,$filedata);
                    181:         if (defined($result)) { warn 'Error:'.$result; return 0; }
1.1       matthew   182:     }
1.4       matthew   183:     return $modified;
1.1       matthew   184: }
                    185: 
                    186: #################################################################
                    187: #################################################################
                    188: 
                    189: =pod
                    190: 
                    191: =item &parse_config_file
                    192: 
                    193: Read a configuration file in and parse it into an internal data structure.
                    194: 
                    195: Input: filename
                    196: 
                    197: Output: array ref $filedata  OR  scalar error message
                    198: 
                    199: =cut
                    200: 
                    201: #################################################################
                    202: #################################################################
                    203: sub parse_config_file {
                    204:     my ($file) = @_;
                    205:     open(INFILE,$file) || return ('Unable to open '.$file.' for reading');
                    206:     my @Input = <INFILE>;
                    207:     close(INFILE);
                    208:     my @Structure;
                    209:     my %Sections;
                    210:     while (my $line = shift(@Input)) {
                    211:         chomp($line);
                    212:         if ($line =~ /^\[([^\]]*)\]/) {
                    213:             my $section_id = $1;
                    214:             push(@Structure,'__section__'.$section_id);
                    215:             while ($line = shift(@Input)) {
1.4       matthew   216:                 chomp($line);
1.1       matthew   217:                 if ($line =~ /^\[([^\]]*)\]/) {
                    218:                     unshift(@Input,$line);
                    219:                     last;
                    220:                 } else {
                    221:                     push(@{$Sections{$section_id}},$line);
                    222:                 }
                    223:             }
                    224:         } else {
                    225:             push(@Structure,$line);
                    226:         }
                    227:     }
                    228:     my $filedata = [\@Structure,\%Sections];
                    229:     return $filedata;
                    230: }
                    231: 
                    232: #################################################################
                    233: #################################################################
                    234: 
                    235: =pod
                    236: 
                    237: =item
                    238: 
                    239: Write a configuration file out based on the internal data structure returned
                    240: by &parse_config_file
                    241: 
                    242: Inputs: filename, $filedata (the return value of &parse_config_file
                    243: 
                    244: Returns: undef on success, scalar error message on failure.
                    245: 
                    246: =cut
                    247: 
                    248: #################################################################
                    249: #################################################################
                    250: sub write_config_file {
                    251:     my ($file,$filedata) = @_;
                    252:     my ($structure,$sections) = @$filedata;
                    253:     if (! defined($structure) || ! ref($structure)) {
                    254:         return 'Bad subroutine inputs';
                    255:     }
                    256:     open(OUTPUT,'>'.$file) || return('Unable to open '.$file.' for writing');
                    257:     for (my $i=0;$i<scalar(@$structure);$i++) {
                    258:         my $line = $structure->[$i];
                    259:         chomp($line);
                    260:         if ($line =~ /^__section__(.*)$/) {
                    261:             my $section_id = $1;
                    262:             print OUTPUT ('['.$section_id.']'.$/);
                    263:             foreach my $section_line (@{$sections->{$section_id}}) {
                    264:                 chomp($section_line);
                    265:                 print OUTPUT $section_line.$/;
                    266:             }
                    267:             # Deal with blank lines
                    268:             if ($sections->{$section_id}->[-1] =~ /^\s*$/) {
                    269:                 # No need to output a blank line at the end if there is one 
                    270:                 # already
                    271:             } else {
                    272:                 print OUTPUT $/;
                    273:             }
                    274:         } else {
                    275:             print OUTPUT $line.$/;
                    276:         }
                    277:     }
                    278:     close OUTPUT;
                    279:     return undef;
                    280: }
                    281: 
                    282: #################################################################
                    283: #################################################################
                    284: 
                    285: =pod
                    286: 
                    287: =item &modify_config_file
                    288: 
                    289: Modifies the internal data structure of a configuration file to include new
                    290: sections and/or new configuration directives.
                    291: 
                    292: Inputs: $filedata (see &parse_config_file
                    293: $section, the [section] the new entry is to reside in.  A value of undef will
                    294: cause the "outer" section (as in yum.conf) to be updated (or have the new
                    295: value prepended).
                    296: $newkey: A line which matches this will be replaced with $newkey.$newvalue
                    297: $newvalue: The new value to be placed with the new key.
                    298: 
1.4       matthew   299: Returns: 0 or 1, indicating if the file was modified(1) or not(0).
                    300: 
                    301: 
1.1       matthew   302: =cut
                    303: 
                    304: #################################################################
                    305: #################################################################
                    306: sub modify_config_file {
                    307:     my ($filedata,$section,$newkey,$newvalue)=@_;
1.4       matthew   308:     my $modified = 0;    # returned value - set to true if the file is modified
1.1       matthew   309:     my ($structure,$sections) = @$filedata;
                    310:     if (! defined($newvalue)) {
                    311:         $newvalue = '';
                    312:     }
                    313:     my $newline = $newkey.$newvalue;
                    314:     #
                    315:     # Determine which array ref gets the item
                    316:     my $target;
                    317:     if (defined($section)) {
                    318:         if (! exists($sections->{$section})) {
                    319:             push(@$structure,'__section__'.$section);
                    320:             $sections->{$section}=[];
                    321:         }
                    322:         $target = $sections->{$section};
                    323:     } else {
                    324:         $target = $structure;
                    325:     }
                    326:     #
                    327:     # Put the item in or update it.
                    328:     my $key_is_new = 1;
                    329:     for (my $i=0;$i<scalar(@$target);$i++) {
                    330:         if ($target->[$i] =~/^$newkey/) {
1.4       matthew   331:             if ($target->[$i] ne $newline) {
                    332:                 $target->[$i]=$newline;
                    333:                 $modified = 1;
                    334:             }
1.1       matthew   335:             $key_is_new = 0;
                    336:             last;
                    337:         }
                    338:     }
                    339:     if ($key_is_new) {
                    340:         if (! defined($section)) {
                    341:             unshift(@$target,$newline);
                    342:         } else {
                    343:             # No need to put things after a blank line.
1.2       matthew   344:             if (defined($target->[-1]) && $target->[-1] =~ /^\s*$/) {
1.1       matthew   345:                 $target->[-1] = $newline;
1.4       matthew   346:                 $modified = 1;
1.1       matthew   347:             } else {
                    348:                 push(@$target,$newline);
1.4       matthew   349:                 $modified = 1;
1.1       matthew   350:             }
                    351:         }
                    352:     }
1.4       matthew   353:     return $modified;
1.1       matthew   354: }
                    355: 
                    356: 
                    357: #################################################################
                    358: #################################################################
                    359: 
                    360: =pod
                    361: 
                    362: =back
                    363: 
                    364: =cut
                    365: 
                    366: #################################################################
                    367: #################################################################

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