X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FLeiMirror.pm;h=e20d30b48546fc9c1344d78b9d699858af4db0a6;hb=23af251dd607c4e75ab1e68063f2c885c48cc035;hp=5cfa6fea851c9d11b6979228e9e950c49adef69d;hpb=b43c5ef05e5803ba0c49f700b7bbd8b6e81ee41c;p=public-inbox.git diff --git a/lib/PublicInbox/LeiMirror.pm b/lib/PublicInbox/LeiMirror.pm index 5cfa6fea..e20d30b4 100644 --- a/lib/PublicInbox/LeiMirror.pm +++ b/lib/PublicInbox/LeiMirror.pm @@ -7,11 +7,13 @@ use strict; use v5.10.1; use parent qw(PublicInbox::IPC); use PublicInbox::Config; +use PublicInbox::AutoReap; use IO::Uncompress::Gunzip qw(gunzip $GunzipError); use IO::Compress::Gzip qw(gzip $GzipError); -use PublicInbox::Spawn qw(popen_rd spawn run_die); +use PublicInbox::Spawn qw(popen_rd spawn); use File::Temp (); use Fcntl qw(SEEK_SET O_CREAT O_EXCL O_WRONLY); +use Carp qw(croak); sub _wq_done_wait { # dwaitpid callback (via wq_eof) my ($arg, $pid) = @_; @@ -20,7 +22,7 @@ sub _wq_done_wait { # dwaitpid callback (via wq_eof) if ($?) { $lei->child_error($?); } elsif (!unlink($f)) { - $lei->err("unlink($f): $!") unless $!{ENOENT}; + warn("unlink($f): $!\n") unless $!{ENOENT}; } else { if ($lei->{cmd} ne 'public-inbox-clone') { $lei->lazy_cb('add-external', '_finish_' @@ -89,24 +91,31 @@ sub clone_cmd { @cmd; } +sub ft_rename ($$$) { + my ($ft, $dst, $open_mode) = @_; + my $fn = $ft->filename; + my @st = stat($dst); + my $mode = @st ? ($st[2] & 07777) : ($open_mode & ~umask); + chmod($mode, $ft) or croak "E: chmod $fn: $!"; + rename($fn, $dst) or croak "E: rename($fn => $ft): $!"; + $ft->unlink_on_destroy(0); +} + sub _get_txt { # non-fatal - my ($self, $endpoint, $file) = @_; + my ($self, $endpoint, $file, $mode) = @_; my $uri = URI->new($self->{src}); my $lei = $self->{lei}; my $path = $uri->path; chop($path) eq '/' or die "BUG: $uri not canonicalized"; $uri->path("$path/$endpoint"); - my $cmd = $self->{curl}->for_uri($lei, $uri, '--compressed'); - my $ce = "$self->{dst}/$file"; - my $ft = File::Temp->new(TEMPLATE => "$file-XXXX", - UNLINK => 1, DIR => $self->{dst}); - my $opt = { 0 => $lei->{0}, 1 => $ft, 2 => $lei->{2} }; + my $ft = File::Temp->new(TEMPLATE => "$file-XXXX", DIR => $self->{dst}); + my $opt = { 0 => $lei->{0}, 1 => $lei->{1}, 2 => $lei->{2} }; + my $cmd = $self->{curl}->for_uri($lei, $uri, + qw(--compressed -R -o), $ft->filename); my $cerr = run_reap($lei, $cmd, $opt); return "$uri missing" if ($cerr >> 8) == 22; return "# @$cmd failed (non-fatal)" if $cerr; - my $f = $ft->filename; - rename($f, $ce) or return "rename($f, $ce): $! (non-fatal)"; - $ft->unlink_on_destroy(0); + ft_rename($ft, "$self->{dst}/$file", $mode); undef; # success } @@ -119,8 +128,9 @@ sub _try_config { File::Path::mkpath($dst); -d $dst or die "mkpath($dst): $!\n"; } - my $err = _get_txt($self, qw(_/text/config/raw inbox.config.example)); - return $self->{lei}->err($err) if $err; + my $err = _get_txt($self, + qw(_/text/config/raw inbox.config.example), 0444); + return warn($err, "\n") if $err; my $f = "$self->{dst}/inbox.config.example"; my $cfg = PublicInbox::Config->git_config_dump($f, $self->{lei}->{2}); my $ibx = $self->{ibx} = {}; @@ -149,8 +159,8 @@ sub set_description ($) { sub index_cloned_inbox { my ($self, $iv) = @_; my $lei = $self->{lei}; - my $err = _get_txt($self, qw(description description)); - $lei->err($err) if $err; # non fatal + my $err = _get_txt($self, qw(description description), 0666); + warn($err, "\n") if $err; # non fatal eval { set_description($self) }; warn $@ if $@; @@ -183,11 +193,8 @@ sub index_cloned_inbox { sub run_reap { my ($lei, $cmd, $opt) = @_; $lei->qerr("# @$cmd"); - $opt->{pgid} = 0 if $lei->{sock}; - my $pid = spawn($cmd, undef, $opt); - my $reap = PublicInbox::OnDestroy->new($lei->can('sigint_reap'), $pid); - waitpid($pid, 0) == $pid or die "waitpid @$cmd: $!"; - @$reap = (); # cancel reap + my $ar = PublicInbox::AutoReap->new(spawn($cmd, undef, $opt)); + $ar->join; my $ret = $?; $? = 0; # don't let it influence normal exit $ret; @@ -379,7 +386,7 @@ sub try_manifest { my ($path_pfx, $v1_path, @v2_epochs) = deduce_epochs($m, $path); if (@v2_epochs) { # It may be possible to have v1 + v2 in parallel someday: - $lei->err(<json->encode($m); gzip(\$json => $fn) or die "gzip: $GzipError"; } - my $fin = "$self->{dst}/manifest.js.gz"; - rename($fn, $fin) or die "E: rename($fn, $fin): $!"; - $ft->unlink_on_destroy(0); + ft_rename($ft, "$self->{dst}/manifest.js.gz", 0666); } sub start_clone_url { @@ -417,6 +422,7 @@ sub start_clone_url { sub do_mirror { # via wq_io_do my ($self) = @_; my $lei = $self->{lei}; + umask($lei->{client_umask}) if defined $lei->{client_umask}; eval { my $iv = $lei->{opt}->{'inbox-version'}; if (defined $iv) { @@ -441,17 +447,17 @@ sub start { require PublicInbox::Inbox; require PublicInbox::Admin; require PublicInbox::InboxWritable; + $lei->request_umask; my ($op_c, $ops) = $lei->workers_start($self, 1); $lei->{wq1} = $self; $self->wq_io_do('do_mirror', []); - $self->wq_close(1); + $self->wq_close; $lei->wait_wq_events($op_c, $ops); } sub ipc_atfork_child { my ($self) = @_; $self->{lei}->_lei_atfork_child; - $SIG{TERM} = sub { exit(128 + 15) }; # trigger OnDestroy $reap $self->SUPER::ipc_atfork_child; }