Add a command to check the job status and reset it

Signed-off-by: Benjamin Brahmer <info@b-brahmer.de>
This commit is contained in:
Benjamin Brahmer 2023-03-20 14:08:52 +01:00
parent ca9e07b3ba
commit 17f0fc7f4a
8 changed files with 195 additions and 15 deletions

View File

@ -5,8 +5,8 @@ The format is mostly based on [Keep a Changelog](https://keepachangelog.com/en/1
# Unreleased
## [24.x.x]
### Changed
- Drop support for Nextcloud 25, Supported: 26, 27
- Drop support for Nextcloud 25, Supported: 26, 27 (#2316)
- Add a new command for occ `./occ news:updater:job` allows to check and reset the update job (#2166)
### Fixed
# Releases

View File

@ -75,6 +75,7 @@ Report a [feed issue](https://github.com/nextcloud/news/discussions/new)
<command>OCA\News\Command\Updater\UpdateUser</command>
<command>OCA\News\Command\Updater\BeforeUpdate</command>
<command>OCA\News\Command\Updater\AfterUpdate</command>
<command>OCA\News\Command\Updater\Job</command>
<command>OCA\News\Command\Config\FolderList</command>
<command>OCA\News\Command\Config\FolderAdd</command>
<command>OCA\News\Command\Config\FolderDelete</command>

View File

@ -32,7 +32,6 @@ Since an attacker can not execute code in contrast to mixed active content, but
### Why don't you simply use an HTTPS image/audio/video proxy?
For the same reason that we can't fix non HTTPS websites: It does not fix the underlying issue, but only silences it. If you are using an image HTTPS proxy, an attacker can simply attack your image proxy since the proxy fetches insecure content. **Even worse**: if your image proxy serves these images from the same domain as your Nextcloud installation, you are [vulnerable to XSS via SVG images](https://www.owasp.org/images/0/03/Mario_Heiderich_OWASP_Sweden_The_image_that_called_me.pdf). In addition, people feel safe when essentially they are not.
Since most people don't understand mixed content and don't have two domains and a standalone server for the image proxy, it is very likely they will choose to host it under the same domain.
@ -50,25 +49,78 @@ This is very often caused by missing or old files, e.g. by failing to upload all
Feeds can be updated using Nextcloud's system cron or an external updater via the API. **The feed update is not run in Webcron and AJAX cron mode!**
### Validating Using System Cron
!!! info
This requires Nextcloud 26 or newer and News 24.0.0 or newer.
Follow this checklist:
- Check admin settings of Nextcloud, was the last cron execution ok.
- Check the News admin settings, system cron is used to update news
- You should see a info card at the top, which will tell you when the last job execution was.
- If the card is red it is very likely that the update job is stuck.
- If it is green then maybe only some feeds are failing to update, check the Nextcloud logs.
If you believe the job is stuck you can reset it. For further steps you need to use occ.
You can check again the status of the job.
(replace www-data with your httpd user)
```bash
sudo -u www-data php ./occ news:updater:job
Checking update Status
Last Execution was 2023-03-20 12:20:03 UTC
```
If you think the job is stuck you can reset it, this may lead to issues if the job is currently running!
```bash
sudo -u www-data php ./occ news:updater:job --reset
Checking update Status
Last Execution was 2023-03-20 12:20:03 UTC
Attempting to reset the job.
Done, job should execute on next schedule.
```
The output of the command should have changed.
```bash
sudo -u www-data php ./occ news:updater:job
Checking update Status
Last Execution was 1970-01-01 00:00:00 UTC
```
After some time has passed the timestamp should be close to the current time.
If this did not help, check the logs and open a issue or discussion on GitHub.
#### Outdated Steps
Follow these steps if you are running an older version of News and Nextcloud.
* Check if you are using the system cron (Cron) setting on the admin page. AJAX and Web cron will not update feeds
* Check if the cronjob exists with crontab -u www-data -e (replace www-data with your httpd user)
* Check if the cronjob exists with `crontab -u www-data -e` (replace www-data with your httpd user)
* Check the file permissions of the cron.php file and if www-data (or whatever your httpd user is called like) can read and execute that script
* Check if you can execute the cron with sudo -u www-data php -f nextcloud/cron.php (replace www-data with your httpd user)
* Check your data/nextcloud.log for errors
* Check if the cronjob is ever executed by placing an error_log('updating'); in the background job file. If the cronjob runs, there should be an updating log statement in your httpd log.
* Check if you can execute the cron with `sudo -u www-data php -f nextcloud/cron.php` (replace www-data with your httpd user)
* Check your `data/nextcloud.log` for errors
* Check if the cronjob is ever executed by placing an `error_log('updating');` in the [background job file](https://github.com/nextcloud/news/blob/master/lib/Service/UpdaterService.php#L55). If the cronjob runs, there should be an updating log statement in your httpd log.
* If there is no updating statement in your logs check if your cronjob is executed by executing a different script
* Check if the oc_jobs table has a reserved_at entry with a value other than 0. If it does for whatever reason, set it to 0. You can check this by executing:
#### Info
```sql
SELECT * from oc_jobs WHERE class LIKE '%News%' ORDER BY id;
```
* In newer versions of News (21.x.x) the old job OCA\News\Cron\Updater was removed from the DB.
You will get two rows where column class will be `OCA\News\Cron\Updater` and `OCA\News\Cron\UpdaterJob`.
Reset the reserved_at by executing:
!!! info
sql UPDATE oc_jobs SET reserved_at = 0 WHERE id = < id from above SELECT statement > ;
In newer versions of News (21.x.x) the old job OCA\News\Cron\Updater was removed from the DB.
If your cron works fine, but Nextcloud's cronjobs are never executed, file a bug in [server](https://github.com/nextcloud/server/).
Reset the reserved_at by executing
```sql
UPDATE oc_jobs SET reserved_at = 0 WHERE id = <id from above SELECT statement>;
```
If your cron works fine, but Nextcloud's cronjobs are never executed, file a bug in [server](https://github.com/nextcloud/server/)
### Using External Updater

View File

@ -0,0 +1,76 @@
<?php
/**
* Nextcloud - News
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*/
namespace OCA\News\Command\Updater;
use DateTime;
use OCP\Util;
use OCA\News\Service\StatusService;
use OCA\News\Service\UpdaterService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Job extends Command
{
/**
* @var StatusService Status service
*/
private $statusService;
/**
* @var UpdaterService Update service
*/
private $updaterService;
public function __construct(StatusService $statusService, UpdaterService $updaterService)
{
parent::__construct();
$this->statusService = $statusService;
$this->updaterService = $updaterService;
}
/**
* @return void
*/
protected function configure()
{
$this->setName('news:updater:job')
->addOption(
'reset',
null,
InputOption::VALUE_NONE,
'If the job should be reset, warning this might lead to issues.'
)
->setDescription('Console API for checking the update job status and to reset it.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$reset = (bool) $input->getOption('reset');
[$major, $minor, $micro] = Util::getVersion();
if ($major < 26) {
$output->writeln("Error: This only works with Nextcloud 26 or newer.");
return 1;
}
$output->writeln("Checking update Status");
$date = new DateTime();
$date->setTimestamp($this->statusService->getUpdateTime());
$output->writeln("Last Execution was ".$date->format('Y-m-d H:i:s e'));
if ($reset) {
$output->writeln("Attempting to reset the job.");
$this->updaterService->reset();
$output->writeln("Done, job should execute on next schedule.");
}
return 0;
}
}

View File

@ -14,6 +14,9 @@
namespace OCA\News\Service;
use OCP\BackgroundJob\IJobList;
use OCA\News\Cron\UpdaterJob;
class UpdaterService
{
@ -32,14 +35,19 @@ class UpdaterService
*/
private $itemService;
/** @var IJobList */
private $jobList;
public function __construct(
FolderServiceV2 $folderService,
FeedServiceV2 $feedService,
ItemServiceV2 $itemService
ItemServiceV2 $itemService,
IJobList $jobList
) {
$this->folderService = $folderService;
$this->feedService = $feedService;
$this->itemService = $itemService;
$this->jobList = $jobList;
}
@ -60,4 +68,14 @@ class UpdaterService
{
$this->itemService->purgeOverThreshold();
}
public function reset(): int
{
$myJobList = $this->jobList->getJobsIterator(UpdaterJob::class, 1, 0);
$job = $myJobList->current();
$this->jobList->resetBackgroundJob($job);
return 0;
}
}

View File

@ -18,6 +18,8 @@ use OCA\News\Service\FolderServiceV2;
use OCA\News\Service\ItemServiceV2;
use OCA\News\Service\UpdaterService;
use PHPUnit\Framework\TestCase;
use OCP\BackgroundJob\IJobList;
use OCP\BackgroundJob\IJob;
class UpdaterTest extends TestCase
{
@ -42,6 +44,11 @@ class UpdaterTest extends TestCase
*/
private $updater;
/**
* @var \PHPUnit\Framework\MockObject\MockObject|IJobList
*/
private $jobList;
protected function setUp(): void
{
$this->folderService = $this->getMockBuilder(FolderServiceV2::class)
@ -53,10 +60,14 @@ class UpdaterTest extends TestCase
$this->itemService = $this->getMockBuilder(ItemServiceV2::class)
->disableOriginalConstructor()
->getMock();
$this->jobList = $this->getMockBuilder(IJobList::class)
->disableOriginalConstructor()
->getMock();
$this->updater = new UpdaterService(
$this->folderService,
$this->feedService,
$this->itemService
$this->itemService,
$this->jobList
);
}
@ -83,4 +94,5 @@ class UpdaterTest extends TestCase
->method('fetchAll');
$this->updater->update();
}
}

21
tests/command/update.bats Normal file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env bats
# This only works with NC 26
load "helpers/settings"
load "../test_helper/bats-support/load"
load "../test_helper/bats-assert/load"
TESTSUITE="Update"
@test "[$TESTSUITE] Job status" {
run ./occ news:updater:job
assert_success
}
@test "[$TESTSUITE] Job reset" {
run ./occ news:updater:job --reset
assert_success
}

@ -1 +1 @@
Subproject commit 78fa631d1370562d2cd4a1390989e706158e7bf0
Subproject commit ffe84ea5dd43b568851549b3e241db150c12929c