diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index 894b94401..0d1634296 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -1,5 +1,6 @@ 7.7.17 - fixed #10654: Story Archive: Search not working properly + - fixed #10692: Unprivileged users can stop spectre - fixed search indexer concatenates keywords to content. - fixed Index Story fields for Search (headline, subtitle, location, byline, highlights, story) - fixed #10619: Pagination macro diff --git a/docs/gotcha.txt b/docs/gotcha.txt index de03ef753..fcdad233e 100644 --- a/docs/gotcha.txt +++ b/docs/gotcha.txt @@ -9,6 +9,12 @@ save you many hours of grief. 7.7.17 -------------------------------------------------------------------- + * Spectre now works like many other programs and writes a PID + file. The location of that file is required to be in your + spectre.conf file to start or stop. After installing this + version, you will need to manually kill spectre and then + restart it. + * The Default Gallery Album View Thumbnails template has been reworked to get rid of intermittent rendering bugs with IE7. The thumbnail pop-up is now completely CSS. The thumbnails.js file is still available, diff --git a/etc/spectre.conf.original b/etc/spectre.conf.original index 62971e4a1..84788b754 100644 --- a/etc/spectre.conf.original +++ b/etc/spectre.conf.original @@ -46,7 +46,11 @@ # It should be safe to set this to 1 any time spectre and WebGUI # are running on the same server. -"ignoreEnvProxy" : 0 +"ignoreEnvProxy" : 0, + +# The location of the file that keeps track of the master spectre processId. + +"pidFile" : "/var/run/spectre.pid" } diff --git a/lib/Spectre/Admin.pm b/lib/Spectre/Admin.pm index 0f23aa036..53f340b3e 100644 --- a/lib/Spectre/Admin.pm +++ b/lib/Spectre/Admin.pm @@ -26,6 +26,21 @@ use Spectre::Cron; use Spectre::Workflow; +#------------------------------------------------------------------- + +=head2 _safe_shutdown ( ) + +Stops the kernel when TERM signal is received + +=cut + +sub _safe_shutdown { + my ($obj) = @_[ OBJECT ]; + $obj->error('Spectre shut down'); + POE::Kernel->stop; +} + + #------------------------------------------------------------------- =head2 _start ( ) @@ -41,22 +56,9 @@ sub _start { $kernel->alias_set($serviceName); $kernel->call( IKC => publish => $serviceName, $publicEvents ); $kernel->delay_set("loadSiteData",3); + $kernel->sig( TERM => '_safe_shutdown' ); } -#------------------------------------------------------------------- - -=head2 _stop ( ) - -Gracefully shuts down the admin interface. - -=cut - -sub _stop { - my ($kernel, $self) = @_[KERNEL, OBJECT]; - $self->debug("Stopping Spectre administrative manager."); - undef $self; - $kernel->stop; -} #------------------------------------------------------------------- @@ -204,8 +206,8 @@ sub new { name => 'Spectre' ); POE::Session->create( - object_states => [ $self => {_start=>"_start", _stop=>"_stop", "shutdown"=>"_stop", "ping"=>"ping", "loadSiteData"=>"loadSiteData"} ], - args=>[["shutdown","ping"]] + object_states => [ $self => {_start=>"_start", "ping"=>"ping", "loadSiteData"=>"loadSiteData", "_safe_shutdown" => "_safe_shutdown"} ], + args=>[["ping"]] ); Spectre::Workflow->new($config, $logger, $debug); Spectre::Cron->new($config, $logger, $debug); diff --git a/sbin/spectre.pl b/sbin/spectre.pl index 6c531c981..893f5ba6e 100755 --- a/sbin/spectre.pl +++ b/sbin/spectre.pl @@ -68,17 +68,22 @@ STOP } if ($shutdown) { - my $remote = create_ikc_client( - port=>$config->get("port"), - ip=>$config->get("ip"), - name=>rand(100000), - timeout=>10 - ); - die $POE::Component::IKC::ClientLite::error unless $remote; - my $result = $remote->post('admin/shutdown'); - die $POE::Component::IKC::ClientLite::error unless defined $result; - $remote->disconnect; - undef $remote; + local $/; + my $pidFileName = $config->get('pidFile'); + if (! $pidFileName) { + die "No pidFile specified in spectre.conf\n"; + } + open my $pidFile, '<', $pidFileName or + die "Unable to open pidFile ($pidFileName) for writing: $!\n"; + my $spectrePid = <$pidFile>; + close $pidFile or + die "Unable to close pidFile ($pidFileName) after writing: $!\n"; + chomp $spectrePid; + kill 15, $spectrePid; + sleep 1; + kill 9, $spectrePid; + unlink $pidFileName or + die "Unable to remove PID file\n"; } elsif ($ping) { my $res = ping(); @@ -95,18 +100,31 @@ elsif ($run) { Spectre::Admin->new($config, $debug); } elsif ($daemon) { + my $pidFileName = $config->get('pidFile'); if (!ping()) { die "Spectre is already running.\n"; } + elsif (-e $pidFileName){ + die "pidFile $pidFileName already exists\n"; + } #fork and exit(sleep(1) and print((ping())?"Spectre failed to start!\n":"Spectre started successfully!\n")); #Can't have right now. require POSIX; fork and exit; POSIX::setsid(); + ##Write the PID file + if (! $pidFileName) { + die "No pidFile specified in spectre.conf\n"; + } + open my $pidFile, '>', $pidFileName or + die "Unable to open pidFile ($pidFileName) for writing: $!\n"; chdir "/"; open STDIN, "+>", File::Spec->devnull; open STDOUT, "+>&STDIN"; open STDERR, "+>&STDIN"; fork and exit; + print $pidFile $$."\n"; + close $pidFile or + die "Unable to close pidFile ($pidFileName) after writing: $!\n"; Spectre::Admin->new($config, $debug); }