initial checkin
[rersyncrecent.git] / bin / rrr-update
blob56685977d6fd16ca7220ded6a6cce9d20eb39f3a
1 #!/usr/bin/perl
3 =head1 NAME
5 rrr-update - add a file to/delete a file from the dataset
7 =head1 SYNOPSIS
9 rrr-update [options] principalfile file
11 =head1 OPTIONS
13 =over 8
15 =cut
17 my @opt = <<'=back' =~ /B<--(\S+)>/g;
19 =item B<--add>
21 Inject a 'new' event.
23 =item B<--delete>
25 Inject a 'delete' event.
27 =item B<--dry-run|n>
29 Does nothing, only prints what it would do.
31 =item B<--epoch=s>
33 Set the epoch of the file to this value. Normally epoch is set to
34 current time as a floating point value. This option can be used to
35 inject old events that have been forgotten somehow. Triggers setting
36 of the dirtymark of the whole dataset which means all slaves are
37 forced to restart their mirroring activity.
39 Be aware that this is not only costly to downstream servers, it is
40 also slow: it calls aggregate twice with force.
42 =item B<--help|h>
44 Prints a brief message and exists.
46 =item B<--verbose|v+>
48 More feedback.
50 =back
52 =head1 DESCRIPTION
54 When you later discover missing files...
56 The principalfile argument is the path to local principal recentfile.
58 The file argument is a relative path calculated from the localroot
59 directory of the recentfile object.
62 =cut
65 use strict;
66 use warnings;
68 use File::Find qw(find);
69 use lib "/home/k/sources/rersyncrecent/lib";
70 use File::Rsync::Mirror::Recent;
71 use File::Spec;
72 use Getopt::Long;
73 use Pod::Usage qw(pod2usage);
75 our %Opt;
76 GetOptions(\%Opt,
77 @opt,
78 ) or pod2usage(1);
80 if ($Opt{help}) {
81 pod2usage(0);
84 if (@ARGV != 2) {
85 pod2usage(1);
88 my($principal,$file) = @ARGV;
89 my $recc = File::Rsync::Mirror::Recent->new
90 (local => $principal);
91 my($rf) = $recc->principal_recentfile;
92 my($abs_file,$rel_file);
93 if (File::Spec->file_name_is_absolute($file)) {
94 $rel_file = substr($file,length $rf->localroot);
95 $abs_file = $file;
96 } else {
97 $rel_file = $file;
98 $abs_file = File::Spec->catfile($rf->localroot,$file);
101 my $type = "new";
102 if ($Opt{delete}) {
103 my $news = $recc->news(contains => { path => $rel_file });
104 if (@$news) {
105 warn "Found file:\n".YAML::Syck::Dump $news;
106 } else {
107 die "Didn't find '$file' in this recentfile collection, giving up.";
109 $type = "delete";
110 } elsif ($Opt{add}) {
111 my $news = $recc->news(contains => { path => $rel_file });
112 if (@$news) {
113 warn "Info: found file in index:\n".YAML::Syck::Dump $news;
115 $type = "new";
118 my $epoch = $Opt{epoch};
119 if (defined $epoch) {
120 if ($Opt{"dry-run"}) {
121 warn sprintf "Would call update on directory %s with args abs_file[%s], type[%s], epoch[%s] and then aggregate with force twice.\n",
122 $rf->localroot, $abs_file, $type, $epoch;
123 } else {
124 $rf->update($abs_file,$type,$epoch);
125 warn localtime()." starting first aggregate\n";
126 $rf->aggregate(force => 1);
127 warn localtime()." starting second aggregate\n";
128 $rf->aggregate(force => 1);
130 } else {
131 if ($Opt{"dry-run"}) {
132 warn sprintf "Would call update on directory %s with args abs_file[%s], type[%s].\n",
133 $rf->localroot, $abs_file, $type, $epoch;
134 } else {
135 $rf->update($abs_file,$type);
140 __END__
143 # Local Variables:
144 # mode: cperl
145 # coding: utf-8
146 # cperl-indent-level: 4
147 # End: