aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-05-24 17:56:31 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-05-24 18:03:37 +0300
commita5e383a975b4ab3ca9012521953eb3c64277072a (patch)
tree07ee0f2daab79db1f7e78a86717cab3f942963b8
parent94a2603878b98bc6c10fc3b3fcfbe2d4ba7abdbc (diff)
downloadglacier-a5e383a975b4ab3ca9012521953eb3c64277072a.tar.gz
glacier-a5e383a975b4ab3ca9012521953eb3c64277072a.tar.bz2
Implement upload of multiple files in a single command
* lib/App/Glacier/Command.pm (new): Fix call to the abend method. * lib/App/Glacier/Command/Purge.pm: Default to interactive mode. * lib/App/Glacier/Command/Put.pm: Upload multiple files, if -m (--multiple) option is given. * lib/App/Glacier/Progress.pm (new): Call display.
-rw-r--r--lib/App/Glacier/Command.pm2
-rw-r--r--lib/App/Glacier/Command/Purge.pm6
-rw-r--r--lib/App/Glacier/Command/Put.pm79
-rw-r--r--lib/App/Glacier/Progress.pm1
4 files changed, 77 insertions, 11 deletions
diff --git a/lib/App/Glacier/Command.pm b/lib/App/Glacier/Command.pm
index d49c5be..136fc50 100644
--- a/lib/App/Glacier/Command.pm
+++ b/lib/App/Glacier/Command.pm
@@ -203,7 +203,7 @@ sub new {
$region = $creds->region($account) unless defined $region;
}
}
- abend(EX_CONFIG, "no access credentials found")
+ $self->abend(EX_CONFIG, "no access credentials found")
unless ($self->{_config}->isset(qw(glacier access))
&& $self->{_config}->isset(qw(glacier secret)));
}
diff --git a/lib/App/Glacier/Command/Purge.pm b/lib/App/Glacier/Command/Purge.pm
index 91f0b6c..6ce595b 100644
--- a/lib/App/Glacier/Command/Purge.pm
+++ b/lib/App/Glacier/Command/Purge.pm
@@ -28,11 +28,11 @@ Removes all archives from the vault.
=item B<-f>, B<--force>
-Remove all without asking. This is the default.
+Remove all without asking.
=item B<-i>, B<--interactive>
-Ask for confirmation before proceeding.
+Ask for confirmation before proceeding. This is the default.
=back
@@ -44,6 +44,7 @@ B<glacier>(1).
sub getopt {
my ($self, %opts) = @_;
+ $self->{_options}{interactive} = 1;
$self->SUPER::getopt(
'interactive|i' => \$self->{_options}{interactive},
'force|f' => sub { $self->{_options}{interactive} = 0 },
@@ -68,6 +69,7 @@ sub run {
my $ver = 1;
foreach my $arch (@{$info}) {
$self->debug(1, "deleting $file;$ver");
+ return if $self->dry_run;
$self->glacier_eval('delete_archive',
$vault_name, $arch->{ArchiveId});
if ($self->lasterr) {
diff --git a/lib/App/Glacier/Command/Put.pm b/lib/App/Glacier/Command/Put.pm
index da5780b..954488c 100644
--- a/lib/App/Glacier/Command/Put.pm
+++ b/lib/App/Glacier/Command/Put.pm
@@ -7,6 +7,8 @@ use App::Glacier::Job::InventoryRetrieval;
use App::Glacier::Progress;
use parent qw(App::Glacier::Command);
use File::Basename;
+use File::stat;
+use Fcntl ':mode';
use Scalar::Util;
use Carp;
@@ -17,9 +19,10 @@ glacier put - upload file to a vault
=head1 SYNOPSIS
B<glacier put>
-[B<-q>]
+[B<-mq>]
[B<-j> I<NJOBS>]
[B<--jobs=>I<NJOBS>]
+[B<--multiple>]
[B<--quiet>]
I<VAULT>
I<FILE>
@@ -44,6 +47,11 @@ Sets the number of concurrent jobs for multiple-part uploads.
The default is configured by the B<transfer.upload.jobs> configuration
statement. If absent, the B<transfer.jobs> statement is used. The
default value is 16.
+
+=item B<-m>, B<--multiple>
+
+Upload multiple files. All command line arguments after I<VAULT> are treated
+as the names of local files to upload.
=back
@@ -57,23 +65,71 @@ sub getopt {
my ($self, %opts) = @_;
return $self->SUPER::getopt('jobs|j=i' => \$self->{_options}{jobs},
'quiet|q' => \$self->{_options}{quiet},
+ 'multiple|m' => \$self->{_options}{multiple},
%opts);
}
sub run {
my $self = shift;
- $self->abend(EX_USAGE, "two or three arguments expected")
- unless @_ == 2 || @_ == 3;
- my ($vaultname, $localname, $remotename) = @_;
- $remotename = basename($localname) unless defined($remotename);
- $self->_upload($vaultname, $localname, $remotename);
+ if ($self->{_options}{multiple}) {
+ $self->abend(EX_USAGE, "too few arguments") if @_ < 2;
+ my $vaultname = shift;
+ my @failed_uploads;
+ foreach my $filename (@_) {
+ eval {
+ $self->_upload($vaultname, $filename);
+ };
+ if ($@) {
+ if ($@ =~ /^__UPLOAD_FAILED__/) {
+ push @failed_uploads, $filename;
+ next
+ }
+ die $@;
+ }
+ }
+ if (@failed_uploads) {
+ if (@failed_uploads == @_) {
+ exit(EX_FAILURE);
+ } else {
+ $self->error("following files failed to upload: "
+ . join(', ', @failed_uploads));
+ exit(EX_UNAVAILABLE);
+ }
+ }
+ } else {
+ $self->abend(EX_USAGE, "two or three arguments expected")
+ unless @_ == 2 || @_ == 3;
+ my ($vaultname, $localname, $remotename) = @_;
+ $self->_upload($vaultname, $localname, $remotename);
+ }
}
+sub abend {
+ my ($self, $code, @msg) = @_;
+ $self->error(@msg);
+ if ($self->{_options}{multiple}) {
+ die "__UPLOAD_FAILED__";
+ } else {
+ exit $code;
+ }
+}
+
+
sub _upload {
my ($self, $vaultname, $localname, $remotename) = @_;
- my $size = -s $localname
- or $self->abend(EX_USAGE, "can't stat \"$localname\": $!");
+ $remotename = basename($localname) unless defined($remotename);
+
+ my $st = stat($localname)
+ or $self->abend(EX_NOINPUT, "can't stat \"$localname\": $!");
+ unless (S_ISREG($st->mode)) {
+ $self->abend(EX_NOPERM, "\"$localname\" is not a regular file");
+ }
+ my $size = $st->size;
+ if ($size == 0) {
+ $self->abend(EX_NOPERM, "\"$localname\": file has zero size");
+ }
+
my $dir = $self->directory($vaultname);
my $id = ($size < $self->cf_transfer_param(qw(upload single-part-size)))
? $self->_upload_simple($vaultname, $localname, $remotename)
@@ -91,11 +147,18 @@ sub _upload_simple {
my ($self, $vaultname, $localname, $remotename) = @_;
$self->debug(1, "uploading $localname in single part");
+ return if $self->dry_run;
+ my $p = new App::Glacier::Progress(1,
+ prefix => $localname,
+ show_percent => 1)
+ unless $self->{_options}{quiet};
my $archive_id = $self->glacier_eval('upload_archive',
$vaultname,
$localname,
$remotename);
+ $p->finish('uploaded') if $p;
+
if ($self->lasterr) {
$self->abend(EX_FAILURE, "upload failed: ",
$self->last_error_message);
diff --git a/lib/App/Glacier/Progress.pm b/lib/App/Glacier/Progress.pm
index 6f51465..3da6eca 100644
--- a/lib/App/Glacier/Progress.pm
+++ b/lib/App/Glacier/Progress.pm
@@ -57,6 +57,7 @@ sub new {
goto ${$self->{_sigwinch}} if defined $self->{_sigwinch};
};
}
+ $self->display;
return $self;
}

Return to:

Send suggestions and report system problems to the System administrator.