diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-05-24 17:56:31 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-05-24 18:03:37 +0300 |
commit | a5e383a975b4ab3ca9012521953eb3c64277072a (patch) | |
tree | 07ee0f2daab79db1f7e78a86717cab3f942963b8 | |
parent | 94a2603878b98bc6c10fc3b3fcfbe2d4ba7abdbc (diff) | |
download | glacier-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.pm | 2 | ||||
-rw-r--r-- | lib/App/Glacier/Command/Purge.pm | 6 | ||||
-rw-r--r-- | lib/App/Glacier/Command/Put.pm | 79 | ||||
-rw-r--r-- | lib/App/Glacier/Progress.pm | 1 |
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; } |