File Coverage

blib/lib/FusionInventory/Agent/Task/Deploy/File.pm
Criterion Covered Total %
statement 21 91 23.0
branch 0 38 0.0
condition 0 14 0.0
subroutine 7 13 53.8
pod 0 5 0.0
total 28 161 17.3


line stmt bran cond sub pod time code
1             package FusionInventory::Agent::Task::Deploy::File;
2              
3 2     2   29394006 use strict;
  2         11  
  2         124  
4 2     2   10 use warnings;
  2         2  
  2         106  
5              
6 2     2   722 use Digest::SHA;
  2         7936  
  2         139  
7 2     2   14 use File::Basename;
  2         2  
  2         190  
8 2     2   11 use File::Path qw(mkpath);
  2         2  
  2         125  
9 2     2   8 use File::Glob;
  2         2  
  2         106  
10 2     2   692 use HTTP::Request;
  2         19881  
  2         30  
11              
12             sub new {
13 0     0 0   my ($class, %params) = @_;
14              
15 0 0         die "no datastore parameter" unless $params{datastore};
16 0 0         die "no sha512 parameter" unless $params{sha512};
17              
18 0   0       my $self = {
19             p2p => $params{data}->{p2p},
20             retention_duration => $params{data}->{'p2p-retention-duration'} || 60 * 24 * 3,
21             uncompress => $params{data}->{uncompress},
22             mirrors => $params{data}->{mirrors},
23             multiparts => $params{data}->{multiparts},
24             name => $params{data}->{name},
25             sha512 => $params{sha512},
26             datastore => $params{datastore},
27             client => $params{client},
28             logger => $params{logger}
29             };
30              
31 0           bless $self, $class;
32              
33 0           return $self;
34             }
35              
36             sub getPartFilePath {
37 0     0 0   my ($self, $sha512) = @_;
38              
39 0 0         return unless $sha512 =~ /^(.)(.)(.{6})/;
40 0           my $subFilePath = $1.'/'.$2.'/'.$3;
41              
42 0           my @storageDirs =
43             File::Glob::glob($self->{datastore}->{path}.'/fileparts/shared/*'),
44             File::Glob::glob($self->{datastore}->{path}.'/fileparts/private/*');
45              
46 0           foreach my $dir (@storageDirs) {
47 0 0         if (-f $dir.'/'.$subFilePath) {
48 0           return $dir.'/'.$subFilePath;
49             }
50             }
51              
52 0           my $filePath = $self->{datastore}->{path}.'/fileparts/';
53             # filepart not found
54 0 0         if ($self->{p2p}) {
55 0           $filePath .= 'shared/';
56             } else {
57 0           $filePath .= 'private/';
58             }
59              
60             # Compute a directory name that will be used to know
61             # if the file must be purge. We don't want a new directory
62             # everytime, so we use a 10h frame
63 0           $filePath .= int(time/10000)*10000 + ($self->{retention_duration} * 60);
64 0           $filePath .= '/'.$subFilePath;
65              
66 0           return $filePath;
67             }
68              
69             sub download {
70 0     0 0   my ($self) = @_;
71              
72 0 0         die unless $self->{mirrors};
73              
74 0           my $mirrorList = $self->{mirrors};
75              
76              
77 0           my $p2pHostList;
78              
79 0           MULTIPART: foreach my $sha512 (@{$self->{multiparts}}) {
  0            
80 0           my $partFilePath = $self->getPartFilePath($sha512);
81 0           File::Path::mkpath(dirname($partFilePath));
82 0 0         if (-f $partFilePath) {
83 0 0         next MULTIPART if $self->_getSha512ByFile($partFilePath) eq $sha512;
84             }
85              
86 0           eval {
87 0 0 0       if ($self->{p2p} && (ref($p2pHostList) ne 'ARRAY') && FusionInventory::Agent::Task::Deploy::P2P->require) {
      0        
88 0           $p2pHostList = FusionInventory::Agent::Task::Deploy::P2P::findPeer(62354, $self->{logger});
89             }
90             };
91 0 0         $self->{logger}->debug("failed to enable P2P: $@") if $@;
92              
93              
94 0           my $lastGood;
95 0           my %remote = (p2p => $p2pHostList, mirror => $mirrorList);
96 0           foreach my $remoteType (qw/p2p mirror/) {
97 0           foreach my $mirror ($lastGood, @{$remote{$remoteType}}) {
  0            
98 0 0         next unless $mirror;
99              
100 0 0         next unless $sha512 =~ /^(.)(.)/;
101 0           my $sha512dir = $1.'/'.$1.$2.'/';
102              
103 0           $self->{logger}->debug($mirror.$sha512dir.$sha512);
104              
105 0           my $request = HTTP::Request->new(GET => $mirror.$sha512dir.$sha512);
106 0           my $response = $self->{client}->request($request, $partFilePath);
107              
108 0 0 0       if ($response && ($response->code == 200) && -f $partFilePath) {
      0        
109 0 0         if ($self->_getSha512ByFile($partFilePath) eq $sha512) {
110 0 0         $lastGood = $mirror if $remoteType eq 'p2p';
111 0           next MULTIPART;
112             }
113 0           $self->{logger}->debug("sha512 failure: $sha512");
114             }
115             # bad file, drop it
116 0           unlink($partFilePath);
117             }
118             }
119             }
120              
121             }
122              
123             sub filePartsExists {
124 0     0 0   my ($self) = @_;
125              
126 0           foreach my $sha512 (@{$self->{multiparts}}) {
  0            
127              
128 0           my $filePath = $self->getPartFilePath($sha512);
129 0 0         return 0 unless -f $filePath;
130              
131             }
132 0           return 1;
133             }
134              
135             sub _getSha512ByFile {
136 0     0     my ($self, $filePath) = @_;
137              
138 0           my $sha = Digest::SHA->new('512');
139              
140 0           my $sha512;
141 0           eval {
142 0           $sha->addfile($filePath, 'b');
143 0           $sha512 = $sha->hexdigest;
144             };
145 0 0         $self->{logger}->debug("SHA512 failure: $@") if $@;
146              
147 0           return $sha512;
148             }
149              
150             sub validateFileByPath {
151 0     0 0   my ($self, $filePath) = @_;
152              
153              
154 0 0         if (-f $filePath) {
155 0 0         if ($self->_getSha512ByFile($filePath) eq $self->{sha512}) {
156 0           return 1;
157             }
158             }
159              
160 0           return 0;
161             }
162              
163              
164             1;