File Coverage

blib/lib/Mirror/YAML.pm
Criterion Covered Total %
statement 23 25 92.0
branch 2 4 50.0
condition n/a
subroutine 8 8 100.0
pod 0 2 0.0
total 33 39 84.6


line stmt bran cond sub pod time code
1             package Mirror::YAML;
2              
3 4     4   622373 use 5.00503;
  4         16  
  4         157  
4 4     4   22 use strict;
  4         9  
  4         113  
5 4     4   1613 use Mirror::URI ();
  4         18  
  4         87  
6 4     4   5897 use Parse::CPAN::Meta ();
  4         6334  
  4         99  
7              
8 4     4   29 use vars qw{$VERSION @ISA};
  4         8  
  4         345  
9             BEGIN {
10 4     4   10 $VERSION = '0.04_01';
11 4         1733 @ISA = 'Mirror::URI';
12             }
13              
14              
15              
16              
17              
18             #####################################################################
19             # Implementation-Specific Methods
20              
21             sub filename {
22 5     5 0 29 return 'mirror.yml';
23             }
24              
25             sub parse {
26 2     2 0 5 my $class = shift;
27              
28             # Make sure we actually have a YAML document
29 2 50       15 unless ( $_[0] =~ /^---/ ) {
30 0         0 return undef;
31             }
32              
33             # Parse the file
34 2         15 my @docs = Parse::CPAN::Meta::Load( $_[0] );
35              
36             # We only care about the first document
37 2 50       18818 if ( defined $docs[0] ) {
38 2         14 return $docs[0];
39             } else {
40 0           Carp::croak("Illegal YAML document");
41             }
42             }
43              
44             1;
45              
46             =pod
47              
48             =head1 NAME
49              
50             Mirror::YAML - Mirror Configuration and Auto-Discovery
51              
52             =head1 DESCRIPTION
53              
54             A C file is used to allow a repository client to reliably and
55             robustly locate, identify, validate and age a repository.
56              
57             It contains a timestamp for when the repository was last updated, the URI
58             for the master repository, and a list of all the current mirrors at the
59             time the repository was last updated.
60              
61             B contains all the functionality requires to both create
62             and read the F files, and the logic to select one or more
63             mirrors entirely automatically.
64              
65             It currently scales cleanly for a dozen or so mirrors, but may be slow
66             when used with very large repositories with a hundred or more mirrors.
67              
68             =head2 Methodology
69              
70             A variety of simple individual mechanisms are combined to provide a
71             completely robust discovery and validation system.
72              
73             B
74              
75             The F file should exist in a standard location, typically at
76             the root of the repository. The file is very small (no more than a few
77             kilobytes at most) so the overhead of fetching one (or several) of them
78             is negligable.
79              
80             The file is pulled via FTP or HTTP. Once pulled, the first three
81             characters are examined to validate it is a YAML file and not a
82             login page for a "captured hotspot" such as at hotels and airports.
83              
84             The shorter ".yml" is used in the file name to allow for Mirror::YAML
85             to be used even in the rare situation of mirrors that must work
86             on operating systems with (now relatively rare) 8.3 filesystems.
87              
88             B
89              
90             Because the F file is small (in simple cases only one or two
91             packets) the download time can be used to measure the responsiveness of
92             that mirror.
93              
94             By pulling the files from several mirrors, the comparative download
95             times can be used as part of the process of selecting the fastest mirror.
96              
97             B
98              
99             The mirror.yml file contains a timestamp that records the last update time
100             for the repository. This timestamp should be updated every repository
101             update cycle, even if there are no actual changes to the repository.
102              
103             Once a F file has been fetched correctly, the timestamp can
104             then be used to verify the age of the mirror. Whereas a perfectly up to
105             date mirror will show an age of less than an hour (assuming that the
106             repository master updates every hour) a repository that has stopped
107             updating will show an age that is greater than the longest mirror rate
108             plus the update cycle time.
109              
110             Thus, any mirror that as "gone stale" can be filter out of the potential
111             mirrors to use.
112              
113             For portability, the timestamp is recording in ISO format Zulu time.
114              
115             B
116              
117             The F file contains a link to the master repository.
118              
119             If the L client has an out-of-date current state at some
120             point, it will use the master repository URI in the current state to
121             pull a fresh F from the master repository.
122              
123             This solves the most-simple case, but other cases require a little
124             more complexity (which we'll address later).
125              
126             B
127              
128             The F file contains a simple list of all mirror URIs.
129              
130             Apart from filtering the list to try and find the best mirror to use,
131             the mirror list allows the B client to have backup
132             options for locating the master repository if it moves, or the
133             bootstrap F file has gotten old.
134              
135             If the client can't find the master repository (because it has moved)
136             the client will scan the list of mirrors to try to find the location
137             of the updated repository.
138              
139             B
140              
141             To bootstrap the client, it should come with a default bootstrap
142             F file built into it. When the client starts up for the
143             first time, it will attempt to fetch an updated mirror.yml from the
144             master repository, and if that doesn't exist will pull from the
145             default list of mirrors until it can find more than one up to date
146             mirror that agrees on the real location of the master server.
147              
148             B
149              
150             On top of the straight forward mirror discovery functionality, the
151             client algorithm contains additional logic to deal with either a
152             mirror or the master server goes bad. While likely not 100% secure
153             it heads off several attack scenarios to prevent anyone trying them,
154             and provides as much as can be expected without resorting to cryto
155             and certificates.
156              
157             =head1 SUPPORT
158              
159             Bugs should be reported via the CPAN bug tracker at
160              
161             L
162              
163             For other issues, or commercial enhancement or support, contact the author.
164              
165             =head1 AUTHOR
166              
167             Adam Kennedy Eadamk@cpan.orgE
168              
169             =head1 SEE ALSO
170              
171             L
172              
173             =head1 COPYRIGHT
174              
175             Copyright 2007 - 2008 Adam Kennedy.
176              
177             This program is free software; you can redistribute
178             it and/or modify it under the same terms as Perl itself.
179              
180             The full text of the license can be found in the
181             LICENSE file included with this module.
182              
183             =cut