]> git.donarmstrong.com Git - debbugs.git/blob - bin/add_bug_to_estraier
include function in instalsql for bin ver/src pkg linking
[debbugs.git] / bin / add_bug_to_estraier
1 #!/usr/bin/perl
2 # add_bug_to_estraier adds a log for a bug to the estaier db, and is
3 # released under the terms of the GPL version 2, or any later version,
4 # at your option. See the file README and COPYING for more
5 # information.
6 # Copyright 2006 by Don Armstrong <don@debian.org>.
7
8
9
10 use warnings;
11 use strict;
12
13
14 use Getopt::Long;
15 use Pod::Usage;
16
17 =head1 NAME
18
19 add_bug_to_estraier -- add a bug log to an estraier database
20
21 =head1 SYNOPSIS
22
23 add_bug_to_estraier [options] < list_of_bugs_to_add
24
25  Options:
26   --url, -u url to estraier node
27   --user, -U user to log into the estraier node
28   --pass, -P password for the estraier node
29   --spool, -s spool location
30   --conf, -c addbug configuration file
31   --cron add all bugs to estraier
32   --timestamp bug timestamp file
33   --debug, -d debugging level (Default 0)
34   --help, -h display this help
35   --man, -m display manual
36
37 =head1 OPTIONS
38
39 =over
40
41 =item B<--url, -u>
42
43 Url to the estraier node
44
45 =item B<--user,-U>
46
47 User to log onto the estraier node
48
49 =item B<--pass,-P>
50
51 Password to log onto the estraier node
52
53 =item B<--spool,-s>
54
55 Spool location; if not set defaults to /etc/debbugs/config
56
57 =item B<--conf,-C>
58
59 Configuration file; a set of key = value pairs separated by newlines;
60 the long name of any option is the name that the configuration file
61 takes
62
63 =item B<--cron>
64
65 Descend through the spool and add all of the bugs to estraier
66
67 =item B<--timestamp>
68
69 Use the timestamp file to only add new bugs; will lock the timestamp
70 file to avoid racing with other invocations
71
72 =item B<--debug, -d>
73
74 Debug verbosity. (Default 0)
75
76 =item B<--help, -h>
77
78 Display brief useage information.
79
80 =item B<--man, -m>
81
82 Display this manual.
83
84 =back
85
86
87 =head1 EXAMPLES
88
89   test_bts --bug 7 --host donbugs.donarmstrong.com
90
91 =head1 DATABASE CREATION
92
93 estcmd create -si -xh3 -attr status str -attr subject str \
94     -attr date num -attr submitter str -attr package str \
95     -attr severity str -attr tags str bts
96
97
98 =cut
99
100
101 use Debbugs::Config qw(:globals);
102 use Debbugs::Mail qw(send_mail_message);
103 use Debbugs::MIME qw(create_mime_message);
104
105 use Search::Estraier;
106 use Debbugs::Estraier qw(:add);
107 use File::Find;
108 use File::stat;
109
110 use vars qw($DEBUG $VERBOSE);
111
112 # XXX parse config file
113
114 my %options = (debug           => 0,
115                help            => 0,
116                man             => 0,
117                url             => undef,
118                user            => undef,
119                passwd          => undef,
120                spool           => undef,
121                conf            => undef,
122                cron            => 0,
123                timestamp       => undef,
124               );
125
126 GetOptions(\%options,'url|u=s','user|U=s','passwd|P=s',
127            'spool|s=s','conf|C=s','cron!','timestamp=s',
128            'debug|d+','help|h|?','man|m');
129
130 my $ERRORS = '';
131
132 if (not defined $options{conf}) {
133      $ERRORS .= "--url must be set\n" if not defined $options{url};
134      $ERRORS .= "--user must be set\n" if not defined $options{user};
135      $ERRORS .= "--passwd must be set\n" if not defined $options{passwd};
136 }
137 else {
138      # Read the conf file
139      my $conf_fh = new IO::File $options{conf},'r'
140           or die "Unable to open $options{conf} for reading";
141      while (<$conf_fh>) {
142           chomp;
143           next if /^\s*\#/;
144           my ($key,$value) = split /\s*[:=]\s*/,$_,2;
145           $options{$key} = $value if defined $key and not defined $options{$key};
146      }
147      $ERRORS .= "url must be set\n" if not defined $options{url};
148      $ERRORS .= "user must be set\n" if not defined $options{user};
149      $ERRORS .= "passwd must be set\n" if not defined $options{passwd};
150 }
151 $ERRORS .= "--spool must be set if --cron is used\n" if
152      not defined $options{spool} and $options{cron};
153 pod2usage($ERRORS) if length $ERRORS;
154
155 pod2usage() if $options{help};
156 pod2usage({verbose=>2}) if $options{man};
157
158
159 $DEBUG = $options{debug};
160
161 $Debbugs::Estraier::DEBUG = $DEBUG;
162 $VERBOSE = 0;
163
164 my $node =  new Search::Estraier::Node (url    => $options{url},
165                                         user   => $options{user},
166                                         passwd => $options{passwd},
167                                        );
168 $gSpoolDir = $options{spool} if defined $options{spool};
169
170 if ($options{cron}) {
171      my %timestamps;
172      my $start_time = time;
173      my $unlink = 0;
174      my %seen_dirs;
175      check_pid($options{timestamp});
176      # read timestamp file
177      if (defined $options{timestamp}) {
178           my $timestamp_fh = new IO::File $options{timestamp},'r' or
179                die "Unable to open timestamp $options{timestamp}: $!";
180           while (<$timestamp_fh>) {
181                chomp;
182                my ($key,$value) = split /\s+/,$_,2;
183                $timestamps{$key} = $value;
184           }
185      }
186      for my $hash (map {sprintf '%02d',$_ } 0..99) {
187           find(sub {
188                     print STDERR "Examining $_\n" if $DEBUG > 1;
189                     return if not /^(\d+)\.log$/;
190                     my $bug_num = $1;
191                     my $stat = stat $_ or next;
192                     return unless -f _;
193                     return if exists $timestamps{$File::Find::dir} and
194                          ($timestamps{$File::Find::dir} > $stat->mtime);
195                     $seen_dirs{$File::Find::dir} = $start_time;
196                     print STDERR "Adding $bug_num\n" if $DEBUG;
197                     my $max_message = 0;
198                     eval{
199                          $max_message = add_bug_log($node,$bug_num);
200                     };
201                     if ($@) {
202                          print STDERR "Adding $bug_num failed with $@\n";
203                     }
204                },
205                map {(-d "$options{spool}/$_/$hash")?
206                          "$options{spool}/$_/$hash":()}
207                qw(db-h archive),
208               );
209           # write timestamp file
210           if (defined $options{timestamp}) {
211                %timestamps = (%timestamps,%seen_dirs);
212                my $timestamp_fh = new IO::File $options{timestamp},'w' or
213                     die "Unable to open timestamp $options{timestamp}: $!";
214                foreach my $key (keys %timestamps) {
215                     print {$timestamp_fh} $key,' ',
216                          $timestamps{$key}||'',qq(\n);
217                }
218           }
219      }
220      unlink("$options{timestamp}.pid");
221 }
222 else {
223      while (my $bug_num = <STDIN>) {
224           chomp $bug_num;
225           add_bug_log($node,$bug_num);
226      }
227 }
228
229
230 sub check_pid{
231      my ($timestamp) = @_;
232      if (-e "${timestamp}.pid") {
233           my $time_fh = new IO::File  "${timestamp}.pid", 'r' or die "Unable to read pidfile";
234           local $/;
235           my $pid = <$time_fh>;
236           if (kill(0,$pid)) {
237                print STDERR "Another cron is running" and exit 0;
238           }
239      }
240      my $time_fh = new IO::File  "${timestamp}.pid", 'w' or
241           die "Unable to read pidfile";
242      print {$time_fh} $$;
243 }
244
245
246 __END__