#!/usr/bin/perl #------------------------------------------------------------------------------- # (C) British Crown Copyright 2006-17 Met Office. # # This file is part of FCM, tools for managing and building source code. # # FCM 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 3 of the License, or # (at your option) any later version. # # FCM 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 FCM. If not, see . #------------------------------------------------------------------------------- use strict; use warnings; use FindBin; use lib "$FindBin::Bin/../lib"; use File::Basename qw{basename}; use File::Spec::Functions qw{catfile}; use IO::File; use Mail::Mailer; use Time::Piece qw{gmtime}; use FCM::Admin::Config; use FCM::Admin::Runner; use FCM::Admin::System qw{ backup_svn_repository backup_trac_environment backup_trac_files get_projects_from_svn_live get_projects_from_trac_live get_users housekeep_svn_hook_logs manage_users_in_svn_passwd manage_users_in_trac_passwd manage_users_in_trac_db_of }; my $THIS = basename($0); my $CONFIG = FCM::Admin::Config->instance(); my $UTIL = $FCM::Admin::Config::UTIL; if (!caller()) { main(@ARGV); } sub main { local(@ARGV) = @_; # Redirects STDOUT and STDERR to the $out_file open(my $old_out, q{>&}, \*STDOUT) || die("$THIS: cannot duplicate STDOUT ($!)\n"); open(my $old_err, q{>&}, \*STDERR) || die("$THIS: cannot duplicate STDERR ($!)\n"); my $log_dir = $UTIL->file_tilde_expand($CONFIG->get_log_dir()); my $now = gmtime(); my $day_of_week = lc($now->day_of_week()); # 0=sun, 1=mon, etc my $day = lc($now->day()); # lower case day of week, e.g. sun, mon my $out_file = catfile($log_dir, "$THIS-$day_of_week$day.log"); open(STDOUT, q{>}, $out_file) || die("$THIS: cannot redirect STDOUT ($!)\n"); open(STDERR, q{>&}, \*STDOUT) || die("$THIS: cannot redirect STDERR ($!)\n"); do_tasks(); # Restores STDOUT and STDERR open(STDERR, q{>&}, $old_err) || die("$THIS: cannot reinstate STDERR ($!)\n"); open(STDOUT, q{>&}, $old_out) || die("$THIS: cannot reinstate STDOUT ($!)\n"); notify($out_file); } # ------------------------------------------------------------------------------ # Performs the daily update tasks. sub do_tasks { # (no argument) my $RUNNER = FCM::Admin::Runner->instance(); my @svn_projects = get_projects_from_svn_live(); my @trac_projects = get_projects_from_trac_live(); my $user_ref = undef; $RUNNER->run_continue( "retrieving user accounts", sub {$user_ref = get_users(); 1;}, ); if (defined($user_ref)) { if ($CONFIG->get_svn_passwd_file()) { $RUNNER->run_continue( "updating SVN user accounts", sub {manage_users_in_svn_passwd($user_ref)}, ); } if ($CONFIG->get_trac_passwd_file()) { $RUNNER->run_continue( "updating Trac user accounts", sub {manage_users_in_trac_passwd($user_ref)}, ); } for my $project (@trac_projects) { $RUNNER->run_continue( "updating Trac accounts in $project", sub {manage_users_in_trac_db_of($project, $user_ref)}, ); } } for my $project (@svn_projects) { $RUNNER->run_continue( "housekeep SVN repository logs for $project", sub {housekeep_svn_hook_logs($project)}, ); $RUNNER->run_continue( "backing up SVN repository for $project", sub {backup_svn_repository({}, $project)}, ); } for my $project (@trac_projects) { $RUNNER->run_continue( "backing up Trac environment for $project", sub {backup_trac_environment({}, $project)}, ); } $RUNNER->run_continue("backing up Trac files", \&backup_trac_files); } # ------------------------------------------------------------------------------ # Notifies on completion. sub notify { my ($out_file) = @_; # Reports number of arguments in subject. my @exceptions = FCM::Admin::Runner->instance()->get_exceptions(); my $subject = sprintf(qq{$THIS finished with %d error(s)}, scalar(@exceptions)); my $mailer = Mail::Mailer->new(); $mailer->open({ From => $CONFIG->get_notification_from(), To => $CONFIG->get_admin_email(), Subject => $subject, }); # Summarises the exceptions at the beginning of the message $mailer->print(qq{$subject:\n}); for my $exception (@exceptions) { $mailer->print(qq{ $exception}); } $mailer->print(qq{\n}); # Prints content of the output $mailer->print(q{#} x 72 . qq{\n}); $mailer->print(qq{# Output and error output of $THIS:\n}); $mailer->print(q{#} x 72 . qq{\n}); my $out_file_handle = IO::File->new($out_file); if (defined($out_file_handle)) { while (my $line = $out_file_handle->getline()) { $mailer->print($line); } $out_file_handle->close(); } $mailer->close(); } __END__ =head1 NAME fcm-daily-update =head1 SYNOPSIS fcm-daily-update =head1 DESCRIPTION This program performs the daily update for the FCM system. =head1 COPYRIGHT E<169> Crown copyright Met Office. All rights reserved. =cut