Skip to content

Conversation

@archanaserver
Copy link
Contributor

@archanaserver archanaserver commented Nov 27, 2025

Introduce Foreman::Cron with a hard-coded mapping from hourly/daily/weekly/monthly to existing rake tasks, and add cron:hourly, cron:daily, cron:weekly and cron:monthly rake tasks.

These serve as generic entrypoints for scheduling (e.g. systemd timers in foremanctl) instead of wiring individual tasks.

Related to: theforeman/foremanctl#288 (review)

@archanaserver
Copy link
Contributor Author

Also the failure looks unrelated to the changes

@evgeni
Copy link
Member

evgeni commented Dec 9, 2025

Also the failure looks unrelated to the changes

Yepp, that's a regression in facterdb

@evgeni
Copy link
Member

evgeni commented Dec 9, 2025

The tests were fixed in #10794 -- if you rebase CI should turn green.

I think Foreman::Cron could use some tests too ;-)

@archanaserver
Copy link
Contributor Author

I think Foreman::Cron could use some tests too ;-)

fair, working on it :/

@evgeni
Copy link
Member

evgeni commented Dec 12, 2025

This needs a redmine, and the test setup fixed, but other than that it looks good!

Thanks!

@archanaserver
Copy link
Contributor Author

This needs a redmine, and the test setup fixed, but other than that it looks good!

@evgeni seems like redmine is not accessible atm

@evgeni
Copy link
Member

evgeni commented Dec 15, 2025

This needs a redmine, and the test setup fixed, but other than that it looks good!

@evgeni seems like redmine is not accessible atm

Fixed it now.

@archanaserver archanaserver changed the title Add cron rake tasks for recurring jobs Fixes #38956 - Add cron rake tasks for recurring jobs Dec 15, 2025
@archanaserver archanaserver force-pushed the cron-rake-tasks branch 2 times, most recently from c600fe2 to 43d493c Compare December 17, 2025 08:35
@archanaserver archanaserver requested a review from evgeni December 17, 2025 08:45
Introduce `Foreman::Cron` with a hard-coded mapping from
hourly/daily/weekly/monthly to existing rake tasks, and add
`cron:hourly`, `cron:daily`, `cron:weekly` and `cron:monthly` rake tasks.

These serve as generic entrypoints for scheduling (e.g. systemd
timers in foremanctl) instead of wiring individual tasks.

Allow plugins to register extra tasks in Foreman::Cron

Fail cron:* rake tasks when a job fails

Refine Foreman::Cron task

Add unit tests for Foreman::Cron

unified registry
@archanaserver
Copy link
Contributor Author

@evgeni i see that db fixture error is unrelated to this fix, and rest is working fine now.

Comment on lines +53 to +55
succeeding = mock('succeeding_task')
succeeding.expects(:reenable).once
succeeding.expects(:invoke).once
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failure is related

Failure: test_0005_run returns true when a task fails but continues executing others

not all expectations were satisfied
unsatisfied expectations:
- expected exactly once, invoked never: #<Mock:succeeding_task>.invoke(any_parameters)
- expected exactly once, invoked never: #<Mock:succeeding_task>.reenable(any_parameters)
satisfied expectations:
- allowed any number of times, invoked never: #<AnyInstance:Resolv::DNS>.getaddresses(any_parameters)
- allowed any number of times, invoked never: #<AnyInstance:Resolv::DNS>.getaddress(any_parameters)
- allowed any number of times, invoked never: #<AnyInstance:Resolv::DNS>.getnames(any_parameters)
- allowed any number of times, invoked never: #<AnyInstance:Resolv::DNS>.getname(any_parameters)
- expected exactly once, invoked once: #<Mock:failing_task>.invoke(any_parameters)
- expected exactly once, invoked once: #<Mock:failing_task>.reenable(any_parameters)
- allowed any number of times, invoked never: Rake::Task.[]("second")
- allowed any number of times, invoked once: Rake::Task.[]("first")

Seems that the succeeding task is never executed?

Comment on lines +69 to +71
def logger
@logger ||= Rails.logger
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the default Rails logger results in the logging to happen to /var/log/foreman/production.log, not stdout:

[root@ip-10-0-167-37 ~]# foreman-rake cron:hourly
W, [2025-12-19T02:10:18.445410 #202382]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:10:18.775945 #202382]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:10:18.992318 #202382]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:10:19.055307 #202382]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:10:19.271063 #202382]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:10:19.523901 #202382]  WARN -- : Scoped order is ignored, it's forced to be batch order.

[root@ip-10-0-167-37 ~]# grep Foreman::Cron /var/log/foreman/production.log
2025-12-19T02:10:20 [I|app|] Foreman::Cron[hourly]: running 1 task(s)
2025-12-19T02:10:20 [I|app|] Foreman::Cron[hourly]: starting ldap:refresh_usergroups
2025-12-19T02:10:20 [I|app|] Foreman::Cron[hourly]: finished ldap:refresh_usergroups

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Logger.new($stdout) (or Logger.new($stderr) - but I think stdout is right) instead works:

[root@ip-10-0-167-37 ~]# foreman-rake cron:hourly
W, [2025-12-19T02:22:16.740554 #202577]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:22:17.077076 #202577]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:22:17.298995 #202577]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:22:17.361471 #202577]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:22:17.582867 #202577]  WARN -- : Scoped order is ignored, it's forced to be batch order.
W, [2025-12-19T02:22:17.837891 #202577]  WARN -- : Scoped order is ignored, it's forced to be batch order.
I, [2025-12-19T02:22:18.655119 #202577]  INFO -- : Foreman::Cron[hourly]: running 1 task(s)
I, [2025-12-19T02:22:18.655201 #202577]  INFO -- : Foreman::Cron[hourly]: starting ldap:refresh_usergroups
I, [2025-12-19T02:22:18.658580 #202577]  INFO -- : Foreman::Cron[hourly]: finished ldap:refresh_usergroups

require 'foreman/cron'

# Register built-in recurring tasks for each cadence.
# Plugins can also call Foreman::Cron.register(:daily, 'my_plugin:task').
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add this to https://github.com/theforeman/foreman/blob/develop/developer_docs/how_to_create_a_plugin.asciidoc

Also, where should they do this? I did that in the register_plugin initializer (in engine.rb of the plugin), and it worked, but is that the recommended place?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants