X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FAdmin.pm;h=9ff59bca3eea304198090585e93eb6f2946853a0;hb=b45a1dffa647f6427d0c900fcc55753db7a1994c;hp=c972fb680a80da9b6ce5e9b0cf75c12a73fcf170;hpb=3e9888ed30b7fe092b03789d19a8020d4bc0fb39;p=public-inbox.git diff --git a/lib/PublicInbox/Admin.pm b/lib/PublicInbox/Admin.pm index c972fb68..9ff59bca 100644 --- a/lib/PublicInbox/Admin.pm +++ b/lib/PublicInbox/Admin.pm @@ -1,4 +1,4 @@ -# Copyright (C) 2019-2020 all contributors +# Copyright (C) 2019-2021 all contributors # License: AGPL-3.0+ # common stuff for administrative command-line tools @@ -10,6 +10,7 @@ our @EXPORT_OK = qw(setup_signals); use PublicInbox::Config; use PublicInbox::Inbox; use PublicInbox::Spawn qw(popen_rd); +use PublicInbox::Eml; *rel2abs_collapsed = \&PublicInbox::Config::rel2abs_collapsed; sub setup_signals { @@ -27,6 +28,27 @@ sub setup_signals { }; } +sub resolve_eidxdir { + my ($cd) = @_; + my $try = $cd // '.'; + my $root_dev_ino; + while (1) { # favor v2, first + if (-f "$try/ei.lock") { + return rel2abs_collapsed($try); + } elsif (-d $try) { + my @try = stat _; + $root_dev_ino //= do { + my @root = stat('/') or die "stat /: $!\n"; + "$root[0]\0$root[1]"; + }; + return undef if "$try[0]\0$try[1]" eq $root_dev_ino; + $try .= '/..'; # continue, cd up + } else { + die "`$try' is not a directory\n"; + } + } +} + sub resolve_inboxdir { my ($cd, $ver) = @_; my $try = $cd // '.'; @@ -106,11 +128,24 @@ sub resolve_inboxes ($;$$) { $cfg or die "--all specified, but $cfgfile not readable\n"; @$argv and die "--all specified, but directories specified\n"; } - + my (@old, @ibxs, @eidx); + if ($opt->{-eidx_ok}) { + require PublicInbox::ExtSearchIdx; + my $i = -1; + @$argv = grep { + $i++; + if (defined(my $ei = resolve_eidxdir($_))) { + $ei = PublicInbox::ExtSearchIdx->new($ei, $opt); + push @eidx, $ei; + undef; + } else { + 1; + } + } @$argv; + } my $min_ver = $opt->{-min_inbox_version} || 0; # lookup inboxes by st_dev + st_ino instead of {inboxdir} pathnames, # pathnames are not unique due to symlinks and bind mounts - my (@old, @ibxs); if ($opt->{all}) { $cfg->each_inbox(sub { my ($ibx) = @_; @@ -127,7 +162,7 @@ sub resolve_inboxes ($;$$) { for (my $i = 0; $i <= $#dirs; $i++) { my $dir = $dirs[$i]; my @st = stat($dir) or die "stat($dir): $!\n"; - $dir = resolve_inboxdir($dir, \(my $ver)); + $dir = $dirs[$i] = resolve_inboxdir($dir, \(my $ver)); if ($ver >= $min_ver) { $s2i{"$st[0]\0$st[1]"} //= $i; } else { @@ -160,7 +195,7 @@ sub resolve_inboxes ($;$$) { die "-V$min_ver inboxes not supported by $0\n\t", join("\n\t", @old), "\n"; } - @ibxs; + $opt->{-eidx_ok} ? (\@ibxs, \@eidx) : @ibxs; } # TODO: make Devel::Peek optional, only used for daemon @@ -241,14 +276,12 @@ sub index_inbox { } local %SIG = %SIG; setup_signals(\&index_terminate, $ibx); - my $warn_cb = $SIG{__WARN__} // sub { print STDERR @_ }; my $idx = { current_info => $ibx->{inboxdir} }; - my $warn_ignore = PublicInbox::InboxWritable->can('warn_ignore'); local $SIG{__WARN__} = sub { - return if $warn_ignore->(@_); - $warn_cb->($idx->{current_info}, ': ', @_); + return if PublicInbox::Eml::warn_ignore(@_); + warn($idx->{current_info}, ': ', @_); }; - if (ref($ibx) && $ibx->version == 2) { + if ($ibx->version == 2) { eval { require PublicInbox::V2Writable }; die "v2 requirements not met: $@\n" if $@; $ibx->{-creat_opt}->{nproc} = $jobs; @@ -271,10 +304,11 @@ EOM $idx = PublicInbox::SearchIdx->new($ibx, 1); } $idx->index_sync($opt); + $idx->{nidx} // 0; # returns number processed } -sub progress_prepare ($) { - my ($opt) = @_; +sub progress_prepare ($;$) { + my ($opt, $dst) = @_; # public-inbox-index defaults to quiet, -xcpdb and -compact do not if (defined($opt->{quiet}) && $opt->{quiet} < 0) { @@ -286,7 +320,8 @@ sub progress_prepare ($) { $opt->{1} = $null; # suitable for spawn() redirect } else { $opt->{verbose} ||= 1; - $opt->{-progress} = sub { print STDERR @_ }; + $dst //= *STDERR{GLOB}; + $opt->{-progress} = sub { print $dst @_ }; } } @@ -326,9 +361,9 @@ sub index_prepare ($$) { $opt->{batch_size} and $env = { XAPIAN_FLUSH_THRESHOLD => '4294967295' }; - for my $k (qw(sequential_shard)) { + for my $k (qw(sequential-shard)) { my $git_key = "publicInbox.index".ucfirst($k); - $git_key =~ s/_([a-z])/\U$1/g; + $git_key =~ s/-([a-z])/\U$1/g; defined(my $s = $opt->{$k} // $cfg->{lc($git_key)}) or next; defined(my $v = $cfg->git_bool($s)) or die "`$git_key=$s' not boolean\n"; @@ -337,4 +372,12 @@ sub index_prepare ($$) { $env; } +sub do_chdir ($) { + my $chdir = $_[0] // return; + for my $d (@$chdir) { + next if $d eq ''; # same as git(1) + chdir $d or die "cd $d: $!"; + } +} + 1;