Skip to content

Commit 54f8086

Browse files
committed
Enable local rsync operations
1 parent b3f121a commit 54f8086

File tree

2 files changed

+183
-152
lines changed

2 files changed

+183
-152
lines changed

ChangeLog

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Revision history for Rex
1919
[NEW FEATURES]
2020
- Enable Bash completion of available CLI options
2121
- Add tab completion for Zsh
22+
- Enable local rsync operations
2223

2324
[REVISION]
2425
- Use author tests to check tidiness of bin files

lib/Rex/Commands/Rsync.pm

+182-152
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ require Rex::Exporter;
6060
use base qw(Rex::Exporter);
6161
use vars qw(@EXPORT);
6262

63+
use Rex::Commands qw(FALSE TRUE);
6364
use Rex::Helper::IP;
6465
use Rex::Helper::Path;
66+
use Rex::Helper::Run;
6567

6668
@EXPORT = qw(sync);
6769

@@ -111,11 +113,14 @@ sub sync {
111113
my $server = $current_connection->{server};
112114
my $cmd;
113115

114-
my $port;
115-
my $servername = $server->to_s;
116+
my ( $port, $servername );
116117

117-
( $servername, $port ) =
118-
Rex::Helper::IP::get_server_and_port( $servername, 22 );
118+
if ( defined $server->to_s ) {
119+
( $servername, $port ) =
120+
Rex::Helper::IP::get_server_and_port( $servername, 22 );
121+
}
122+
123+
my $local_connection = defined $servername ? FALSE : TRUE;
119124

120125
my $auth = $current_connection->{conn}->get_auth;
121126

@@ -148,16 +153,33 @@ sub sync {
148153
if ( $opt && exists $opt->{'download'} && $opt->{'download'} == 1 ) {
149154
$dest = resolv_path($dest);
150155
Rex::Logger::debug("Downloading $source -> $dest");
151-
push @rsync_cmd, "rsync -rl -e '\%s' --verbose --stats $params ";
152-
push @rsync_cmd,
153-
"'" . $auth->{user} . "\@" . $servername . ":" . $source . "'";
156+
push @rsync_cmd, "rsync -rl --verbose --stats $params ";
157+
158+
if ( !$local_connection ) {
159+
push @rsync_cmd, "-e '\%s'";
160+
push @rsync_cmd,
161+
"'" . $auth->{user} . "\@" . $servername . ":" . $source . "'";
162+
}
163+
else {
164+
push @rsync_cmd, "'$source'";
165+
}
166+
154167
push @rsync_cmd, "'$dest'";
155168
}
156169
else {
157170
$source = resolv_path($source);
158171
Rex::Logger::debug("Uploading $source -> $dest");
159-
push @rsync_cmd, "rsync -rl -e '\%s' --verbose --stats $params '$source' ";
160-
push @rsync_cmd, "'" . $auth->{user} . "\@$servername:$dest" . "'";
172+
push @rsync_cmd, "rsync -rl --verbose --stats $params";
173+
174+
if ( !$local_connection ) {
175+
push @rsync_cmd, "-e '\%s'";
176+
push @rsync_cmd, "'$source'";
177+
push @rsync_cmd, "'" . $auth->{user} . "\@$servername:$dest" . "'";
178+
}
179+
else {
180+
push @rsync_cmd, "'$source'";
181+
push @rsync_cmd, "'$dest'";
182+
}
161183
}
162184

163185
if (Rex::is_sudo) {
@@ -166,157 +188,109 @@ sub sync {
166188

167189
$cmd = join( " ", @rsync_cmd );
168190

169-
my $pass = $auth->{password};
170-
my @expect_options = ();
171-
172-
my $auth_type = $auth->{auth_type};
173-
if ( $auth_type eq "try" ) {
174-
if ( $server->get_private_key && -f $server->get_private_key ) {
175-
$auth_type = "key";
191+
if ( !$local_connection ) {
192+
my $pass = $auth->{password};
193+
my @expect_options = ();
194+
195+
my $auth_type = $auth->{auth_type};
196+
if ( $auth_type eq "try" ) {
197+
if ( $server->get_private_key && -f $server->get_private_key ) {
198+
$auth_type = "key";
199+
}
200+
else {
201+
$auth_type = "pass";
202+
}
176203
}
177-
else {
178-
$auth_type = "pass";
179-
}
180-
}
181204

182-
if ( $auth_type eq "pass" ) {
183-
$cmd = sprintf( $cmd,
184-
"ssh -o StrictHostKeyChecking=no -o PubkeyAuthentication=no -p $port",
185-
);
186-
push(
187-
@expect_options,
188-
[
189-
qr{Are you sure you want to continue connecting},
190-
sub {
191-
Rex::Logger::debug("Accepting key..");
192-
my $fh = shift;
193-
$fh->send("yes\n");
194-
exp_continue;
195-
}
196-
],
197-
[
198-
qr{password: ?$}i,
199-
sub {
200-
Rex::Logger::debug("Want Password");
201-
my $fh = shift;
202-
$fh->send( $pass . "\n" );
203-
exp_continue;
204-
}
205-
],
206-
[
207-
qr{password for.*:$}i,
208-
sub {
209-
Rex::Logger::debug("Want Password");
210-
my $fh = shift;
211-
$fh->send( $pass . "\n" );
212-
exp_continue;
213-
}
214-
],
215-
[
216-
qr{rsync error: error in rsync protocol},
217-
sub {
218-
Rex::Logger::debug("Error in rsync");
219-
die;
220-
}
221-
],
222-
[
223-
qr{rsync error: remote command not found},
224-
sub {
225-
Rex::Logger::info("Remote rsync command not found");
226-
Rex::Logger::info(
227-
"Please install rsync, or use Rex::Commands::Sync sync_up/sync_down"
228-
);
229-
die;
230-
}
231-
],
232-
233-
);
234-
}
235-
else {
236-
if ( $auth_type eq "key" ) {
205+
if ( $auth_type eq "pass" ) {
237206
$cmd = sprintf( $cmd,
238-
'ssh -i '
239-
. $server->get_private_key
240-
. " -o StrictHostKeyChecking=no -p $port" );
241-
}
242-
else {
243-
$cmd = sprintf( $cmd, 'ssh -o StrictHostKeyChecking=no -p ' . "$port" );
244-
}
245-
push(
246-
@expect_options,
247-
[
248-
qr{Are you sure you want to continue connecting},
249-
sub {
250-
Rex::Logger::debug("Accepting key..");
251-
my $fh = shift;
252-
$fh->send("yes\n");
253-
exp_continue;
254-
}
255-
],
256-
[
257-
qr{password: ?$}i,
258-
sub {
259-
Rex::Logger::debug("Want Password");
260-
my $fh = shift;
261-
$fh->send( $pass . "\n" );
262-
exp_continue;
263-
}
264-
],
265-
[
266-
qr{Enter passphrase for key.*: $},
267-
sub {
268-
Rex::Logger::debug("Want Passphrase");
269-
my $fh = shift;
270-
$fh->send( $pass . "\n" );
271-
exp_continue;
272-
}
273-
],
274-
[
275-
qr{rsync error: error in rsync protocol},
276-
sub {
277-
Rex::Logger::debug("Error in rsync");
278-
die;
279-
}
280-
],
281-
[
282-
qr{rsync error: remote command not found},
283-
sub {
284-
Rex::Logger::info("Remote rsync command not found");
285-
Rex::Logger::info(
286-
"Please install rsync, or use Rex::Commands::Sync sync_up/sync_down"
287-
);
288-
die;
289-
}
290-
],
291-
292-
);
293-
}
294-
295-
Rex::Logger::debug("cmd: $cmd");
296-
297-
eval {
298-
my $exp = Expect->spawn($cmd) or die($!);
299-
300-
eval {
301-
$exp->expect(
302-
Rex::Config->get_timeout,
207+
"ssh -o StrictHostKeyChecking=no -o PubkeyAuthentication=no -p $port",
208+
);
209+
push(
303210
@expect_options,
304211
[
305-
qr{total size is [\d,]+\s+speedup is },
212+
qr{Are you sure you want to continue connecting},
306213
sub {
307-
Rex::Logger::debug("Finished transfer very fast");
214+
Rex::Logger::debug("Accepting key..");
215+
my $fh = shift;
216+
$fh->send("yes\n");
217+
exp_continue;
218+
}
219+
],
220+
[
221+
qr{password: ?$}i,
222+
sub {
223+
Rex::Logger::debug("Want Password");
224+
my $fh = shift;
225+
$fh->send( $pass . "\n" );
226+
exp_continue;
227+
}
228+
],
229+
[
230+
qr{password for.*:$}i,
231+
sub {
232+
Rex::Logger::debug("Want Password");
233+
my $fh = shift;
234+
$fh->send( $pass . "\n" );
235+
exp_continue;
236+
}
237+
],
238+
[
239+
qr{rsync error: error in rsync protocol},
240+
sub {
241+
Rex::Logger::debug("Error in rsync");
242+
die;
243+
}
244+
],
245+
[
246+
qr{rsync error: remote command not found},
247+
sub {
248+
Rex::Logger::info("Remote rsync command not found");
249+
Rex::Logger::info(
250+
"Please install rsync, or use Rex::Commands::Sync sync_up/sync_down"
251+
);
308252
die;
309253
}
254+
],
310255

311-
]
312256
);
313-
314-
$exp->expect(
315-
undef,
257+
}
258+
else {
259+
if ( $auth_type eq "key" ) {
260+
$cmd = sprintf( $cmd,
261+
'ssh -i '
262+
. $server->get_private_key
263+
. " -o StrictHostKeyChecking=no -p $port" );
264+
}
265+
else {
266+
$cmd = sprintf( $cmd, 'ssh -o StrictHostKeyChecking=no -p ' . "$port" );
267+
}
268+
push(
269+
@expect_options,
270+
[
271+
qr{Are you sure you want to continue connecting},
272+
sub {
273+
Rex::Logger::debug("Accepting key..");
274+
my $fh = shift;
275+
$fh->send("yes\n");
276+
exp_continue;
277+
}
278+
],
316279
[
317-
qr{total size is [\d,]+\s+speedup is },
280+
qr{password: ?$}i,
318281
sub {
319-
Rex::Logger::debug("Finished transfer");
282+
Rex::Logger::debug("Want Password");
283+
my $fh = shift;
284+
$fh->send( $pass . "\n" );
285+
exp_continue;
286+
}
287+
],
288+
[
289+
qr{Enter passphrase for key.*: $},
290+
sub {
291+
Rex::Logger::debug("Want Passphrase");
292+
my $fh = shift;
293+
$fh->send( $pass . "\n" );
320294
exp_continue;
321295
}
322296
],
@@ -327,13 +301,69 @@ sub sync {
327301
die;
328302
}
329303
],
304+
[
305+
qr{rsync error: remote command not found},
306+
sub {
307+
Rex::Logger::info("Remote rsync command not found");
308+
Rex::Logger::info(
309+
"Please install rsync, or use Rex::Commands::Sync sync_up/sync_down"
310+
);
311+
die;
312+
}
313+
],
314+
330315
);
316+
}
331317

332-
};
318+
Rex::Logger::debug("cmd: $cmd");
333319

334-
$exp->soft_close;
335-
$? = $exp->exitstatus;
336-
};
320+
eval {
321+
my $exp = Expect->spawn($cmd) or die($!);
322+
323+
eval {
324+
$exp->expect(
325+
Rex::Config->get_timeout,
326+
@expect_options,
327+
[
328+
qr{total size is [\d,]+\s+speedup is },
329+
sub {
330+
Rex::Logger::debug("Finished transfer very fast");
331+
die;
332+
}
333+
334+
]
335+
);
336+
337+
$exp->expect(
338+
undef,
339+
[
340+
qr{total size is [\d,]+\s+speedup is },
341+
sub {
342+
Rex::Logger::debug("Finished transfer");
343+
exp_continue;
344+
}
345+
],
346+
[
347+
qr{rsync error: error in rsync protocol},
348+
sub {
349+
Rex::Logger::debug("Error in rsync");
350+
die;
351+
}
352+
],
353+
);
354+
355+
};
356+
357+
$exp->soft_close;
358+
$? = $exp->exitstatus;
359+
};
360+
}
361+
else {
362+
my $out = i_run $cmd, fail_ok => 1;
363+
if ($? != 0) {
364+
die $out;
365+
}
366+
}
337367

338368
if ($@) {
339369
Rex::Logger::info($@);

0 commit comments

Comments
 (0)