summaryrefslogtreecommitdiffabout
path: root/lib/App/Glacier/Command/Periodic.pm
blob: 51c971868b8635a5e785f759a5f0355256ca0f59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package App::Glacier::Command::Periodic;
use strict;
use warnings;
use App::Glacier::Core;
use parent qw(App::Glacier::Command);
use Carp;
use Data::Dumper;
use File::Basename;
use App::Glacier::Job;

=head1 NAME

glacier periodic - periodic cronjob for Glacier

=head1 SYNOPSIS

B<glacier periodic>

=head1 DESCRIPTION

Scans glacier jobs, cleaning up expired and failed ones and finishing
up completed ones. For each completed archive retrieval job, the
target file is downloaded and stored in directory configured by
the B<transfer.download.cachedir> configuration setting (default -
F</var/lib/glacier/cache>). This file will be removed when the
corresponding jobs expires. For each completed inventory retrieval job,
the vault inventory is obtained and stored in the database.

It is recommended to schedule this command for periodic execution in
your crontab, e.g.:

  */4 * * * *  root  glacier periodic

=cut

sub run {
    my $self = shift;

    my $db = $self->jobdb();
    $db->foreach(sub {
	my ($key, $descr) = @_;
	my $vault = $descr->{VaultARN};
	$vault =~ s{.*:vaults/}{};

	return if $descr->{Completed};
	
	$self->debug(2, "$descr->{JobId} $descr->{Action} $vault");
	if ($descr->{StatusCode} eq 'Failed') {
	    $self->debug(1, "deleting failed $key $vault " .
			     ($descr->{JobDescription} || $descr->{Action}) .
			 $descr->{JobId});
	    $db->delete($key) unless $self->dry_run;
	}

	my $res = $self->glacier->Describe_job($vault, $descr->{JobId});
	if ($self->glacier->lasterr) {
	    if ($self->glacier->lasterr('code') == 404) {
		$self->debug(1, "deleting expired $key $vault " .
			     ($descr->{JobDescription} || $descr->{Action}) .
			     $descr->{JobId});
		$db->delete($key) unless $self->dry_run;
 	    } else {
		$self->error("can't describe job $descr->{JobId}: ",
			     $self->glacier->last_error_message);
	    }
	} elsif (ref($res) ne 'HASH') {
	    croak "describe_job returned wrong datatype (".ref($res).") for \"$descr->{JobId}\"";
	} else {
	    $self->debug(2, $res->{StatusCode});
	    if ($res->{Completed} && $res->{StatusCode} eq 'Succeeded') {
		$self->debug(1, "$descr->{JobId}: processing $descr->{Action} for $vault");
		return if $self->dry_run;
		if ($res->{Action} eq 'InventoryRetrieval') {
		    require App::Glacier::Command::Sync;
		    my $sync = clone App::Glacier::Command::Sync($self);
	            $sync->sync($vault);
		} elsif ($res->{Action} eq 'ArchiveRetrieval') {
		    my $job = App::Glacier::Job->fromdb($self, $vault,
						        $key, $res);
		    my $localname = $self->archive_cache_filename($vault,
							     $res->{ArchiveId});
		    $self->touchdir(dirname($localname));

		    require App::Glacier::Command::Get;
		    my $get = clone App::Glacier::Command::Get($self);
		    $get->download($job, $localname);
	        }
	    }
	    $db->store($key, $res);
	}
		 });
}

1;

     

Return to:

Send suggestions and report system problems to the System administrator.