source: LMDZ5/branches/testing/tools/fcm/templates/utils/recover_svn.pl @ 5427

Last change on this file since 5427 was 1665, checked in by Laurent Fairhead, 12 years ago

Version testing basée sur la r1628

http://lmdz.lmd.jussieu.fr/utilisateurs/distribution-du-modele/versions-intermediaires


Testing release based on r1628

  • Property svn:executable set to *
File size: 5.5 KB
Line 
1#!/usr/bin/perl
2# ------------------------------------------------------------------------------
3# NAME
4#   recover_svn.pl
5#
6# SYNOPSIS
7#   recover_svn.pl [<list of projects>]
8#
9# DESCRIPTION
10#   This command is used to recover live repositories from backups and dumps,
11#   using the following logic:
12#     1. If one or more <projects> are not specified, check the backup directory
13#        for list of projects and available backups.
14#     2. For each available project (or the specified <projects>), check if its
15#        live repository exists. If so, performs an integrity check.
16#     3. If the live repository does not exist or if the integrity check fails,
17#        recover by copying the backup into the live location.
18#     4. Determine the youngest revision of the live repository.
19#     5. Search the dump directory to see if there are dumps for newer
20#        reversions. If so, load them back to the live repository.
21#
22# COPYRIGHT
23#   (C) Crown copyright Met Office. All rights reserved.
24#   For further details please refer to the file COPYRIGHT.txt
25#   which you should have received as part of this distribution.
26# ------------------------------------------------------------------------------
27
28# Standard pragmas:
29use strict;
30use warnings;
31
32# Standard modules:
33use File::Basename;
34use File::Spec;
35use File::Path;
36
37# ------------------------------------------------------------------------------
38
39# Top level locations of live repositories, backups, dumps and hook scripts
40my $logname  = 'fcm';
41my $svn_live = File::Spec->catfile (
42  File::Spec->rootdir (), qw/data local/, $logname, qw/svn live/,
43);
44my $svn_back = File::Spec->catfile ((getpwnam $logname) [7], qw/svn backups/);
45my $svn_dump = File::Spec->catfile ((getpwnam $logname) [7], qw/svn dumps/);
46my $hook_dir = File::Spec->catfile (
47  (getpwnam $logname) [7], qw/FCM work Admin src hook/,
48);
49
50# Arguments
51my %projects = map {$_, 1} @ARGV;
52
53# Search the backup directory to see what are available
54opendir DIR, $svn_back
55  or die $svn_back, ': cannot read directory (', $!, '), abort';
56my %backups = ();
57while (my $file = readdir 'DIR') {
58  next if $file =~ /^\./;
59  next if $file !~ /\.tgz$/;
60  next unless -f File::Spec->catfile ($svn_back, $file);
61
62  (my $project = $file) =~ s/\.tgz$//;
63
64  # If project arguments specified, skip projects that are not in the list
65  next if %projects and not exists $projects{$project};
66
67  # Store project name and its backup location
68  $backups{$project} = File::Spec->catfile ($svn_back, $file);
69}
70closedir DIR;
71
72# Create the live directory if it does not exist
73mkpath $svn_live or die $svn_live, ': cannot create, abort' if not -d $svn_live;
74
75# Exit if no backups found (for list of specified projects)
76if (not keys %backups) {
77  print 'No backup',
78        (keys %projects ? join (' ', (' for', sort keys %projects)) : ''),
79        ' found in ', $svn_back, "\n";
80  exit;
81}
82
83# Search the live directory to see what are available
84for my $project (sort keys %backups) {
85  my $live_dir = File::Spec->catfile ($svn_live, $project);
86
87  # Recovery required if $live_dir does not exist
88  my $recovery = not -d $live_dir;
89
90  # Perform an integrity check if $live_dir exist
91  $recovery = system ('svnadmin', 'verify', $live_dir) unless $recovery;
92
93  if (not $recovery) {
94    print $project, ': live repository appears to be fine.', "\n";
95    next;
96  }
97
98  # Recover to a temporary location first
99  my $temp_dir = $live_dir . '.tmp';
100
101  if (-d $temp_dir) {
102    # Remove $temp_dir if it exists
103    print 'Removing ', $temp_dir, ' ...', "\n";
104    rmtree $temp_dir;
105  }
106
107  # Un-tar the backup
108  print 'Extracting from the backup archive ', $backups{$project}, "\n";
109  ! system (
110    qw/tar -x -z -C/, dirname ($backups{$project}), '-f', $backups{$project},
111  ) or die 'Cannot extract from the backup archive', $backups{$project};
112
113  (my $backup_dir = $backups{$project}) =~ s/\.tgz$//;
114
115  # Recover from backup
116  print 'Copying ', $backup_dir, ' to ', $temp_dir, ' ...', "\n";
117  my @command = ('svnadmin', 'hotcopy', $backup_dir, $temp_dir);
118  system (@command);
119  die join (' ', @command), ' failed (', $?, '), abort' if $?;
120
121  rmtree $backup_dir;
122
123  # Determine the youngest revision of the repository
124  @command     = ('svnlook', 'youngest', $temp_dir);
125  my $youngest = qx(@command)
126    or die $temp_dir, ': cannot determine youngest revision (', $?, ')';
127
128  # Search dump directory to see if there are any later dumps available
129  my $dump_dir = File::Spec->catfile ($svn_dump, $project);
130 
131  if (opendir DIR, $dump_dir) {
132    my @revs = grep {m/^\d+$/ and $_ > $youngest} readdir DIR;
133    closedir DIR;
134
135    # If newer dumps available, load each one back to the repository
136    for my $rev (sort {$a <=> $b} @revs) {
137      print 'Loading dump for revision ', $rev, ' to ', $temp_dir, ' ...', "\n";
138      my $command = 'svnadmin load ' . $temp_dir .
139                    ' <' . File::Spec->catfile ($dump_dir, $rev);
140      system ($command);
141      die $command, ' failed (', $?, '), abort' if $?;
142    }
143
144  } else {
145      warn $project, ': dump directory not available for project';
146  }
147
148  # Move temporary directory to live
149  if (-d $live_dir) {
150    # Remove $live_dir if it exists
151    print 'Removing ', $live_dir, ' ...', "\n";
152    rmtree $live_dir;
153
154    die $live_dir, ': cannot remove' if -d $live_dir;
155  }
156
157  print 'Moving ', $temp_dir, ' to ', $live_dir, ' ...', "\n";
158  rename $temp_dir, $live_dir or die $temp_dir, ': cannot move to: ', $live_dir;
159}
160
161# Reinstate the hook scripts
162my @command = (
163  File::Spec->catfile (dirname ($0), 'install_hook.pl'),
164  $hook_dir,
165  $svn_live,
166);
167
168exec @command or die 'Cannot exec install_hook.pl (', $!, ')';
169
170__END__
Note: See TracBrowser for help on using the repository browser.