getgrav / grav

Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS powered by PHP, Markdown, Twig, and Symfony
https://getgrav.org
MIT License
14.49k stars 1.4k forks source link

Scheduler / cron relying on shell commands #2647

Open ulab opened 5 years ago

ulab commented 5 years ago

I am not a big fan of Grav having to execute shell commands to check for or create cron jobs. This is an issue especially on hosts that disallow exec(), proc_open() and such for security reasons and resulted in fatal errors on my box when navigating to Tools / Scheduler.

Being the admin on my server, I was able to allow the functions, but this is something that might hurt a lot of people.

After manually adding a cron job, which does not necessarily have to be inside of the webserver-users cronjob table (depending on the hoster), I noticed that Grav still reports "Cron Not Available", because it checks by running cron -l which of course does not list a cronjob that is in /etc/cron.d/zzz-customers.

Perhaps it is an option to have the cron script touch() a file on each run and check if it is older than 2 minutes to see if a cron job is running regularly instead?

dgellow commented 4 years ago

To add to what @ulab said, a dependency on cron -l is causing issues in chrooted environments (such as a chrooted php-fpm).

Also, systemd timers or other schedulers exist as alternatives to crontab, the suggested touch() on a file would work with them.

rhukster commented 4 years ago

Cron is really the only semi-universal solution that is 'usually' available on servers. Of course if a server is chrooted, or cron is locked down, it's not going to work. But then nothing is on those hardened servers.

I looked at all the available options during the development of the scheduler, and all the reliable options relied on cron under the covers. If you find something that is better, then I'll evaluate it and see if its something we could use as an alternative in future versions.

ulab commented 4 years ago

This issue is not against having cron jobs per se, but the scheduler relying on a cron command to check if any method of recurring jobs are being run.

I was able to create a cron job in a different way for example, but the scheduler still says "Cron Not Available".

The suggestion is to just check the modification date of a specific file instead of running "cron -l".

This way you can have different methods of recurring jobs as long as they touch the file which allows the scheduler to identify they are being run regularly.

dgellow commented 4 years ago

The solution suggested by @ulab only requires the cronjob (or equivalent) to do a touch /path/to/specific/file in addition to php bin/grav scheduler . That removes the need for both exec and crontab.

ulab commented 4 years ago

Even php bin/grav scheduler could touch the file directly when its run.

Then as long as some kind of mechanism runs the schedular regularly, the system would be able to check if it is run without having to rely on the cron -l command.

bkraegelin commented 3 years ago

I just figured out the same problem on my shared hosting system...

Most other CMS provide a cron.php script, which may be called regularly from any cronjob service on the internet (or may be called using wget http://localhost from cron)

What about this idea? Maybe as an additional plugin like Poor Man's Cron?

codebude commented 1 year ago

Cron is really the only semi-universal solution that is 'usually' available on servers. Of course if a server is chrooted, or cron is locked down, it's not going to work. But then nothing is on those hardened servers.

But is Cron needed at all, @rhukster ? In the end, only a mechanism X is needed, which executes /usr/bin/php bin/grav scheduler 1 once per minute.

As an example: I personally use Supercronic in my Docker containers. Supercronic calls the scheduler once per minute. The Grav jobs are all executed without errors. The function of the scheduler is therefore completely fulfilled. The error message Cron Not Available for user: www-data in Grav admin is therefore misleading to a certain extent.

Proposal:

As far as I can see, the only "hard" dependency to cron at this point is: https://github.com/getgrav/grav/blob/c7680bb50a881abab3a467c65427767fd372b3b2/system/src/Grav/Common/Scheduler/Scheduler.php#L301

If the PHP scheduler (bin/grav scheduler) would simply write away the last call date, you could simply query "is last date < 2 minutes away from now" in the isCrontabSetup method.

This would serve the same purpose, but would also work for other/external cron systems/triggers. In case no cron was found, yes you can always show the recommendation to set up cron (as implemented today).

rhukster commented 1 year ago

even supercronic is ultimately an external cron mechanism. If you would like to submit a pull request to support the existing server-based cron solution, and external ones, i would be willing to review it and potentially merge it.