| 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
|
|
631
|
use v5.12.5; |
|
|
45
|
|
|
|
|
171
|
|
|
26
|
45
|
|
|
45
|
|
235
|
use warnings; |
|
|
45
|
|
|
|
|
100
|
|
|
|
45
|
|
|
|
|
3001
|
|
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
our $VERSION = '1.14.2.2'; # TRIAL VERSION |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
require Rex::Exporter; |
|
31
|
45
|
|
|
45
|
|
394
|
use File::Basename qw(basename); |
|
|
45
|
|
|
|
|
256
|
|
|
|
45
|
|
|
|
|
2606
|
|
|
32
|
45
|
|
|
45
|
|
292
|
use Rex::Config; |
|
|
45
|
|
|
|
|
110
|
|
|
|
45
|
|
|
|
|
441
|
|
|
33
|
45
|
|
|
45
|
|
345
|
use Rex::Commands::Fs; |
|
|
45
|
|
|
|
|
120
|
|
|
|
45
|
|
|
|
|
530
|
|
|
34
|
45
|
|
|
45
|
|
309
|
use Rex::Interface::Fs; |
|
|
45
|
|
|
|
|
124
|
|
|
|
45
|
|
|
|
|
327
|
|
|
35
|
45
|
|
|
45
|
|
1105
|
use Rex::Helper::Path; |
|
|
45
|
|
|
|
|
119
|
|
|
|
45
|
|
|
|
|
3285
|
|
|
36
|
45
|
|
|
45
|
|
290
|
use Rex::Commands::MD5; |
|
|
45
|
|
|
|
|
95
|
|
|
|
45
|
|
|
|
|
290
|
|
|
37
|
45
|
|
|
45
|
|
313
|
use Rex::Commands; |
|
|
45
|
|
|
|
|
96
|
|
|
|
45
|
|
|
|
|
256
|
|
|
38
|
45
|
|
|
45
|
|
547
|
use Rex::Hook; |
|
|
45
|
|
|
|
|
117
|
|
|
|
45
|
|
|
|
|
2553
|
|
|
39
|
|
|
|
|
|
|
|
|
40
|
45
|
|
|
45
|
|
290
|
use vars qw(@EXPORT); |
|
|
45
|
|
|
|
|
92
|
|
|
|
45
|
|
|
|
|
1613
|
|
|
41
|
45
|
|
|
45
|
|
266
|
use base qw(Rex::Exporter); |
|
|
45
|
|
|
|
|
181
|
|
|
|
45
|
|
|
|
|
27711
|
|
|
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
|
|
|
|
|
17
|
my @new_args = Rex::Hook::run_hook( upload => "before", @_ ); |
|
85
|
3
|
50
|
|
|
|
33
|
if (@new_args) { |
|
86
|
0
|
|
|
|
|
0
|
@_ = @new_args; |
|
87
|
|
|
|
|
|
|
} |
|
88
|
3
|
|
|
|
|
41
|
1; |
|
89
|
3
|
50
|
|
3
|
1
|
25
|
} or do { |
|
90
|
0
|
|
|
|
|
0
|
die("Before-Hook failed. Canceling upload() action: $@"); |
|
91
|
|
|
|
|
|
|
}; |
|
92
|
|
|
|
|
|
|
############################## |
|
93
|
|
|
|
|
|
|
|
|
94
|
3
|
|
|
|
|
27
|
my ( $local, $remote ) = @_; |
|
95
|
|
|
|
|
|
|
|
|
96
|
3
|
|
|
|
|
41
|
$local = resolv_path( $local, 1 ); |
|
97
|
3
|
|
|
|
|
12
|
$remote = resolv_path($remote); |
|
98
|
|
|
|
|
|
|
|
|
99
|
3
|
|
|
|
|
97
|
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
|
|
|
|
43
|
unless ($remote) { |
|
104
|
0
|
|
|
|
|
0
|
$remote = basename($local); |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
3
|
|
|
|
|
45
|
$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
|
|
|
|
|
34
|
my $old_local = $local; # for the upload location use the given name |
|
118
|
|
|
|
|
|
|
|
|
119
|
3
|
50
|
33
|
|
|
119
|
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
|
|
|
|
70
|
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
|
|
|
|
100
|
if ( is_dir($remote) ) { |
|
131
|
0
|
|
|
|
|
0
|
$remote = $remote . '/' . basename($old_local); |
|
132
|
|
|
|
|
|
|
} |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Rex::get_current_connection()->{reporter} |
|
135
|
3
|
|
|
|
|
39
|
->report_resource_start( type => "upload", name => $remote ); |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# first get local md5 |
|
138
|
3
|
|
|
|
|
15
|
my $local_md5; |
|
139
|
|
|
|
|
|
|
LOCAL { |
|
140
|
3
|
|
|
3
|
|
66
|
$local_md5 = md5($local); |
|
141
|
3
|
|
|
|
|
101
|
}; |
|
142
|
|
|
|
|
|
|
|
|
143
|
3
|
50
|
|
|
|
122
|
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
|
|
|
|
|
50
|
my $remote_md5 = ""; |
|
149
|
3
|
|
|
|
|
38
|
eval { $remote_md5 = md5($remote); }; |
|
|
3
|
|
|
|
|
68
|
|
|
150
|
|
|
|
|
|
|
|
|
151
|
3
|
|
|
|
|
128
|
my $__ret; |
|
152
|
|
|
|
|
|
|
|
|
153
|
3
|
50
|
33
|
|
|
141
|
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
|
|
|
|
|
90
|
Rex::Logger::debug("Uploading: $local to $remote"); |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
#### check and run before_change hook |
|
164
|
3
|
|
|
|
|
72
|
Rex::Hook::run_hook( upload => "before_change", $local, $remote ); |
|
165
|
|
|
|
|
|
|
############################## |
|
166
|
|
|
|
|
|
|
|
|
167
|
3
|
|
|
|
|
34
|
$__ret = $fs->upload( $local, $remote ); |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
#### check and run after_change hook |
|
170
|
3
|
|
|
|
|
160
|
Rex::Hook::run_hook( upload => "after_change", $local, $remote, $__ret ); |
|
171
|
|
|
|
|
|
|
############################## |
|
172
|
|
|
|
|
|
|
|
|
173
|
3
|
|
|
|
|
75
|
$__ret = { changed => 1, ret => $__ret }; |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
#### check and run before hook |
|
178
|
3
|
|
|
|
|
71
|
Rex::Hook::run_hook( upload => "after", @_, $__ret ); |
|
179
|
|
|
|
|
|
|
############################## |
|
180
|
|
|
|
|
|
|
|
|
181
|
3
|
50
|
|
|
|
49
|
if ( $__ret->{changed} ) { |
|
182
|
|
|
|
|
|
|
Rex::get_current_connection()->{reporter}->report( |
|
183
|
3
|
|
|
|
|
51
|
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
|
|
|
|
|
51
|
->report_resource_end( type => "upload", name => $remote ); |
|
193
|
|
|
|
|
|
|
|
|
194
|
3
|
|
|
|
|
75
|
return $__ret; |
|
195
|
|
|
|
|
|
|
} |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
1; |