line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# (c) Jan Gehring |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 NAME |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
Rex::Commands::Upload - Upload a local file to a remote server |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=head1 DESCRIPTION |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
With this module you can upload a local file via sftp to a remote host. |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
=head1 SYNOPSIS |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
task "upload", "remoteserver", sub { |
16
|
|
|
|
|
|
|
upload "localfile", "/remote/file"; |
17
|
|
|
|
|
|
|
}; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 EXPORTED FUNCTIONS |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
=cut |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
package Rex::Commands::Upload; |
24
|
|
|
|
|
|
|
|
25
|
45
|
|
|
45
|
|
761
|
use v5.12.5; |
|
45
|
|
|
|
|
161
|
|
26
|
45
|
|
|
45
|
|
241
|
use warnings; |
|
45
|
|
|
|
|
105
|
|
|
45
|
|
|
|
|
2877
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
our $VERSION = '1.14.3'; # VERSION |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
require Rex::Exporter; |
31
|
45
|
|
|
45
|
|
312
|
use File::Basename qw(basename); |
|
45
|
|
|
|
|
238
|
|
|
45
|
|
|
|
|
2338
|
|
32
|
45
|
|
|
45
|
|
286
|
use Rex::Config; |
|
45
|
|
|
|
|
104
|
|
|
45
|
|
|
|
|
499
|
|
33
|
45
|
|
|
45
|
|
351
|
use Rex::Commands::Fs; |
|
45
|
|
|
|
|
91
|
|
|
45
|
|
|
|
|
471
|
|
34
|
45
|
|
|
45
|
|
299
|
use Rex::Interface::Fs; |
|
45
|
|
|
|
|
105
|
|
|
45
|
|
|
|
|
301
|
|
35
|
45
|
|
|
45
|
|
1100
|
use Rex::Helper::Path; |
|
45
|
|
|
|
|
131
|
|
|
45
|
|
|
|
|
3173
|
|
36
|
45
|
|
|
45
|
|
280
|
use Rex::Commands::MD5; |
|
45
|
|
|
|
|
87
|
|
|
45
|
|
|
|
|
780
|
|
37
|
45
|
|
|
45
|
|
279
|
use Rex::Commands; |
|
45
|
|
|
|
|
116
|
|
|
45
|
|
|
|
|
255
|
|
38
|
45
|
|
|
45
|
|
553
|
use Rex::Hook; |
|
45
|
|
|
|
|
108
|
|
|
45
|
|
|
|
|
2498
|
|
39
|
|
|
|
|
|
|
|
40
|
45
|
|
|
45
|
|
265
|
use vars qw(@EXPORT); |
|
45
|
|
|
|
|
100
|
|
|
45
|
|
|
|
|
1581
|
|
41
|
45
|
|
|
45
|
|
226
|
use base qw(Rex::Exporter); |
|
45
|
|
|
|
|
85
|
|
|
45
|
|
|
|
|
27143
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
@EXPORT = qw(upload); |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head2 upload($local, $remote) |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Perform an upload. If $remote is a directory the file will be uploaded to that directory. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
task "upload", "remoteserver", sub { |
50
|
|
|
|
|
|
|
upload "localfile", "/path"; |
51
|
|
|
|
|
|
|
}; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
This function supports the following L: |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=over 4 |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=item before |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
This gets executed before anything is done. All original parameters are passed to it. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
The return value of this hook overwrites the original parameters of the function-call. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=item before_change |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
This gets executed right before the new file is written. The local file name, and the remote file name are passed as parameters. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=item after_change |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
This gets executed right after the file was written. On top of the local file name, and the remote file name, any returned results are passed as parameters. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=item after |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
This gets executed right before the C function returns. All original parameters, and any results returned are passed to it. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=back |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
=cut |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub upload { |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
#### check and run before hook |
83
|
|
|
|
|
|
|
eval { |
84
|
3
|
|
|
|
|
22
|
my @new_args = Rex::Hook::run_hook( upload => "before", @_ ); |
85
|
3
|
50
|
|
|
|
15
|
if (@new_args) { |
86
|
0
|
|
|
|
|
0
|
@_ = @new_args; |
87
|
|
|
|
|
|
|
} |
88
|
3
|
|
|
|
|
27
|
1; |
89
|
3
|
50
|
|
3
|
1
|
18
|
} or do { |
90
|
0
|
|
|
|
|
0
|
die("Before-Hook failed. Canceling upload() action: $@"); |
91
|
|
|
|
|
|
|
}; |
92
|
|
|
|
|
|
|
############################## |
93
|
|
|
|
|
|
|
|
94
|
3
|
|
|
|
|
17
|
my ( $local, $remote ) = @_; |
95
|
|
|
|
|
|
|
|
96
|
3
|
|
|
|
|
23
|
$local = resolv_path( $local, 1 ); |
97
|
3
|
|
|
|
|
20
|
$remote = resolv_path($remote); |
98
|
|
|
|
|
|
|
|
99
|
3
|
|
|
|
|
89
|
my $fs = Rex::Interface::Fs->create; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# if remote not set, use name of local. |
102
|
|
|
|
|
|
|
# must be done before the next line. |
103
|
3
|
50
|
|
|
|
20
|
unless ($remote) { |
104
|
0
|
|
|
|
|
0
|
$remote = basename($local); |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
3
|
|
|
|
|
39
|
$local = Rex::Helper::Path::get_file_path( $local, caller() ); |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
# if there is a file called filename.environment then use this file |
110
|
|
|
|
|
|
|
# ex: |
111
|
|
|
|
|
|
|
# upload "files/hosts", "/etc/hosts"; |
112
|
|
|
|
|
|
|
# |
113
|
|
|
|
|
|
|
# rex -E live ... |
114
|
|
|
|
|
|
|
# will first look if files/hosts.live is available, if not it will |
115
|
|
|
|
|
|
|
# use files/hosts |
116
|
|
|
|
|
|
|
|
117
|
3
|
|
|
|
|
22
|
my $old_local = $local; # for the upload location use the given name |
118
|
|
|
|
|
|
|
|
119
|
3
|
50
|
33
|
|
|
66
|
if ( Rex::Config->get_environment |
120
|
|
|
|
|
|
|
&& -f "$local." . Rex::Config->get_environment ) |
121
|
|
|
|
|
|
|
{ |
122
|
0
|
|
|
|
|
0
|
$local = "$local." . Rex::Config->get_environment; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
3
|
50
|
|
|
|
49
|
if ( !-f $local ) { |
126
|
0
|
|
|
|
|
0
|
Rex::Logger::info("File Not Found: $local"); |
127
|
0
|
|
|
|
|
0
|
die("File $local not found."); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
3
|
50
|
|
|
|
57
|
if ( is_dir($remote) ) { |
131
|
0
|
|
|
|
|
0
|
$remote = $remote . '/' . basename($old_local); |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Rex::get_current_connection()->{reporter} |
135
|
3
|
|
|
|
|
18
|
->report_resource_start( type => "upload", name => $remote ); |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# first get local md5 |
138
|
3
|
|
|
|
|
8
|
my $local_md5; |
139
|
|
|
|
|
|
|
LOCAL { |
140
|
3
|
|
|
3
|
|
45
|
$local_md5 = md5($local); |
141
|
3
|
|
|
|
|
83
|
}; |
142
|
|
|
|
|
|
|
|
143
|
3
|
50
|
|
|
|
94
|
if ( !$local_md5 ) { |
144
|
0
|
|
|
|
|
0
|
die("Error getting local md5 sum of $local"); |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# than get remote md5 to test if we need to upload the file |
148
|
3
|
|
|
|
|
27
|
my $remote_md5 = ""; |
149
|
3
|
|
|
|
|
24
|
eval { $remote_md5 = md5($remote); }; |
|
3
|
|
|
|
|
50
|
|
150
|
|
|
|
|
|
|
|
151
|
3
|
|
|
|
|
25
|
my $__ret; |
152
|
|
|
|
|
|
|
|
153
|
3
|
50
|
33
|
|
|
118
|
if ( $local_md5 && $remote_md5 && $local_md5 eq $remote_md5 ) { |
|
|
|
33
|
|
|
|
|
154
|
0
|
|
|
|
|
0
|
Rex::Logger::debug( |
155
|
|
|
|
|
|
|
"local md5 and remote md5 are the same: $local_md5 eq $remote_md5. Not uploading." |
156
|
|
|
|
|
|
|
); |
157
|
0
|
|
|
|
|
0
|
$__ret = { changed => 0, ret => 0 }; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
else { |
160
|
|
|
|
|
|
|
|
161
|
3
|
|
|
|
|
48
|
Rex::Logger::debug("Uploading: $local to $remote"); |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
#### check and run before_change hook |
164
|
3
|
|
|
|
|
54
|
Rex::Hook::run_hook( upload => "before_change", $local, $remote ); |
165
|
|
|
|
|
|
|
############################## |
166
|
|
|
|
|
|
|
|
167
|
3
|
|
|
|
|
39
|
$__ret = $fs->upload( $local, $remote ); |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
#### check and run after_change hook |
170
|
3
|
|
|
|
|
91
|
Rex::Hook::run_hook( upload => "after_change", $local, $remote, $__ret ); |
171
|
|
|
|
|
|
|
############################## |
172
|
|
|
|
|
|
|
|
173
|
3
|
|
|
|
|
48
|
$__ret = { changed => 1, ret => $__ret }; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
#### check and run before hook |
178
|
3
|
|
|
|
|
53
|
Rex::Hook::run_hook( upload => "after", @_, $__ret ); |
179
|
|
|
|
|
|
|
############################## |
180
|
|
|
|
|
|
|
|
181
|
3
|
50
|
|
|
|
27
|
if ( $__ret->{changed} ) { |
182
|
|
|
|
|
|
|
Rex::get_current_connection()->{reporter}->report( |
183
|
3
|
|
|
|
|
37
|
changed => 1, |
184
|
|
|
|
|
|
|
message => "File uploaded. old md5: $remote_md5 new md5: $local_md5" |
185
|
|
|
|
|
|
|
); |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
else { |
188
|
0
|
|
|
|
|
0
|
Rex::get_current_connection()->{reporter}->report( changed => 0, ); |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
Rex::get_current_connection()->{reporter} |
192
|
3
|
|
|
|
|
31
|
->report_resource_end( type => "upload", name => $remote ); |
193
|
|
|
|
|
|
|
|
194
|
3
|
|
|
|
|
58
|
return $__ret; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
1; |