AWS-CLIWrapper
view release on metacpan or search on metacpan
lib/AWS/CLIWrapper.pm view on Meta::CPAN
$max ||= $min;
last;
}
}
$param->{min_count} = $min unless $param->{min_count};
$param->{max_count} = $max unless $param->{max_count};
}
} elsif ($service eq 's3' && $self->awscli_version >= 0.15.0) {
if ($operation !~ /^(?:cp|ls|mb|mv|rb|rm|sync|website)$/) {
return $self->s3api($operation, @_);
}
} elsif ($service eq 's3api' && $self->awscli_version < 0.15.0) {
return $self->s3($operation, @_);
}
while (my($k, $v) = each %$param) {
my @o = param2opt($k, $v);
if ($service eq 's3' && $k =~ /^(?:include|exclude)$/) {
my $optk = shift @o;
@o = map { $optk => $_ } @o;
}
push @cmd, @o;
}
@cmd = map { shell_quote($_) } @cmd;
warn "cmd: ".join(' ', @cmd) if $ENV{AWSCLI_DEBUG};
my $error_re = $self->catch_error_pattern;
my $retries = $error_re ? $self->catch_error_retries : 0;
RETRY: {
$Error = { Message => '', Code => '' };
my $exit_value = $self->_run(\%opt, \@cmd);
my $ret = $self->_handle($service, $operation, $exit_value);
return $ret unless $Error->{Code};
if ($retries-- > 0 and $Error->{Message} =~ $error_re) {
my $delay = $self->catch_error_delay;
warn "Caught error matching $error_re, sleeping $delay seconds before retrying\n"
if $ENV{AWSCLI_DEBUG};
sleep $delay;
redo RETRY;
}
croak $Error->{Message} if $self->{croak_on_error};
return $ret;
}
}
sub _run {
my ($self, $opt, $cmd) = @_;
my $ret;
if (exists $opt->{'nofork'} && $opt->{'nofork'}) {
# better for perl debugger
my($ok, $err, $buf, $stdout_buf, $stderr_buf) = IPC::Cmd::run(
command => join(' ', @$cmd),
timeout => $opt->{timeout} || $self->{timeout},
);
$ret->{stdout} = join "", @$stdout_buf;
$ret->{err_msg} = (defined $err ? "$err\n" : "") . join "", @$stderr_buf;
if ($ok) {
$ret->{exit_code} = 0;
$ret->{timeout} = 0;
} else {
$ret->{exit_code} = 2;
$ret->{timeout} = 1 if defined $err && $err =~ /^IPC::Cmd::TimeOut:/;
}
print "";
} else {
$ret = IPC::Cmd::run_forked(join(' ', @$cmd), {
timeout => $opt->{timeout} || $self->{timeout},
});
}
return $ret;
}
sub _handle {
my ($self, $service, $operation, $ret) = @_;
if ($ret->{exit_code} == 0 && $ret->{timeout} == 0) {
my $json = $ret->{stdout};
warn sprintf("%s.%s[%s]: %s\n",
$service, $operation, 'OK', $json,
) if $ENV{AWSCLI_DEBUG};
local $@;
my($ret) = eval {
# aws s3 returns null HTTP body, so failed to parse as JSON
# Temporary disable __DIE__ handler to prevent the
# exception from decode() from catching by outer
# __DIE__ handler.
local $SIG{__DIE__} = sub {};
$self->json->decode($json);
};
if ($@) {
if ($ENV{AWSCLI_DEBUG}) {
warn $@;
warn qq|stdout: "$ret->{stdout}"|;
warn qq|err_msg: "$ret->{err_msg}"|;
}
return $json || 'success';
}
return $ret;
} else {
my $stdout_str = $ret->{stdout};
if ($stdout_str && $stdout_str =~ /^{/) {
my $json = $stdout_str;
warn sprintf("%s.%s[%s]: %s\n",
$service, $operation, 'NG', $json,
) if $ENV{AWSCLI_DEBUG};
my($ret) = $self->json->decode_prefix($json);
if (exists $ret->{Errors} && ref($ret->{Errors}) eq 'ARRAY') {
$Error = $ret->{Errors}[0];
} elsif (exists $ret->{Response}{Errors}{Error}) {
# old structure (maybe botocore < 0.7.0)
$Error = $ret->{Response}{Errors}{Error};
} else {
$Error = { Message => 'Unknown', Code => 'Unknown' };
( run in 1.039 second using v1.01-cache-2.11-cpan-437f7b0c052 )