Today Foreman (3.5-develop) is compatible with Ruby 2.7 (older was dropped with Foreman 3.4). It is not yet compatible with Ruby 3, but both EL9 and Ubuntu 22.04 both require that compatibility. This is a rough roadmap with the major milestones to run Foreman and Foreman Proxy on the latest EL and Ubuntu versions. It is likely incomplete and we’ll figure out more things along the way.
How to bootstrap a new platform
This is a small reminder of the general steps to get Foreman running on a new platform.
First of all, there are two major projects that can each independently move. These are Foreman and Foreman Proxy. For both, the steps are largely the same.
- Get the core project’s test suite runing on the Ruby version
- Get all plugin’s test suites running on the Ruby version
- Package them
Once they’re packaged, the installer side can be updated. Additionally, on EL there is an SELinux policy.
In reality it’s not so linear. For example, if it’s a previously unpackaged platform, packaging can start even if plugins aren’t ready. Additionally, some installer modules work with core platform components such as dhcp, dns and tftp.
It should also be noted that a new platform doesn’t mean old platforms are dropped. There is always an overlap which allows users to update.
How to apply this into practice now
Ruby 3 is a big change, but many small steps can be taken. I’ll go over them for each project
Foreman
Today Foreman uses Ruby 2.7 and Rails 6.1. Long term we should aim for for Ruby 3.1, but Rails 7.0 is the first version to support it. Previously I played around with this and created Rails 7 & Ruby 3.1 by ekohl · Pull Request #9328 · theforeman/foreman · GitHub. A lot of smaller tasks have already been split off and merged, but it’s a large task that means we should break this up into smaller pieces. Many of these pieces can move in parallel.
A critical set of plugins should be selected. These plugins should all be made compatible with new versions before changing defaults.
Ruby 3.0
A major step is updating to Ruby 3.0. In Ruby 3.0 some gems changed. The Ruby 3.0.0 release notes mention both rss
and rexml
were changed from default to bundled gems. This means they must now be specified as a dependency. Additionally some stdlib modules are now gems.
More significant is kwargs. In Ruby 2 the last argument could be a hash and keywords were stored there. In Ruby 2.7 it became possible to have a separate keyword argument parameter. Ruby 3 removes the old behavior. See Separation of positional and keyword arguments in Ruby 3.0 for more information. This is tracked in #35300. Because of this a lot of gems have dropped Ruby older than 2.7, because it’s very hard to support more. Because of this Foreman 3.4 has set the minimum Ruby version to 2.7. Because of this there are gems which even today raise deprecation messages, such as safemode and graphql. Updating gems is a large part of this task.
This is an incomplete list, but some concrete work that must happen:
- rss as a bundled gem
- Deal with kwargs
- Update safemode
- Update graphql
- Verify all dependencies are Ruby 3 compatible
There are also many more dependencies that could be updated. All of them should be checked.
Once it passes, CI should be modified to also run on Ruby 3.0.
At this point all plugin authors should be notified to perform the same steps and packaging can commence.
Zeitwerk
First of all, there is still some remaining work on Rails 6.1. Updating to Rails 6.1 defaults doesn’t mean we need to have all Rails 6.1 defaults, but at least call load_defaults 6.1
. Not all values must match the defaults, but the test must pass. It’s also fine to do this incrementally (first 5.0, then 5.1, etc). Zeitwerk is considered out of scope for this part.
The next major step is Zeitwerk. The new default loader in Rails 6.1 and only loader in Rails 7. This is a large effort. The first goal should be to use the classic loader, but support using Zeitwerk. Once Foreman itself is compatible, we should give plugin developers some time to update before we switch the default.
Rails 7.0
Once Ruby 3.0 and Zeitwerk are in place, Rails 7 can be the next focus. The Rails 7.0 release notes and upgrading guide should be helpful.
The previous mechanism to support multiple Rails versions stopped working, so it was removed. A new way should be found so Foreman can default to Rails 6.1 but run with Rails 7.0 too. This helps plugin authors migrate.
This also involves packaging work.
Ruby 3.1
This depends on both Ruby 3.0 and Rails. It is largely the same as Ruby 3.0. The Ruby 3.1.0 release notes mentions more gem changes. These are likely all rather trivial. It is also not required since both EL9 and Ubuntu 22.04 have Ruby 3.0, though EL9 also has a Ruby 3.1 module. Given this is likely a small task, it’d be good to support.
Once it passes, CI should be modified to also run on Ruby 3.1.
Again, plugins need to be verified too.
Foreman Proxy
Foreman Proxy is a lot smaller than Foreman, both in the size of the code base and it has fewer dependencies. There are no frameworks to update, so it’s limited to the Ruby updates. Today the test suite already passes, but the dependencies do need to be fixed.
Similar to Foreman, there are also plugins to consider. These are usually small, but still need to be verified.
Packaging can start fairly soon.
Packaging
The initial goal is to only create new platforms, not switch over existing platforms. On Debian/Ubuntu there’s only a single Ruby interpreter so that’s certainly out of scope. On EL there are modules, but that requires the whole package set to be compatible. Instead, the work will start with building the new platforms (EL9 and Ubuntu 22.04) with components that are compatible. This means initializing empty repositories and getting foreman-release
out. Then once components are ready, they are packaged.
It should be noted that today we have gating by pipelines, but that requires more work so initially they will be pushed to nightly without any verification.
Installer
First all individual modules must be made compatible. Many components describe parts that are delivered as part of the OS, such as Apache, PostgreSQL, ISC DHCP, ISC BIND and TFTP. That work can start and in fact already has. Other modules, such as foreman
and foreman_proxy
need a packaged version. This means it depends on the previous steps.
Once a complete scenario is available, the foreman-installer
package itself can be packaged as well. The foreman-proxy-content scenario is the most likely candidate since the underlying pieces are furthest along (Pulp already runs on EL9).
Timeline
All of this work can happen in parallel, but all projects need to be available before it’s officially released. Having looked at the work needed, it’s very likely work won’t be finished before we branch Foreman 3.5 but are not yet ready. We’ll have to decide if we then have an incomplete repository or only have the changes in nightly.
Update 2024-01-22: We have initial EL9 packages using Ruby 3.0 for most packages, except for Foreman and its plugins itself. The goal is to deliver experimental EL9 support in Foreman 3.10. Version 3.11 will be production quality, including a smooth migration path from EL8.