diff --git a/.fixtures.yml b/.fixtures.yml index 571994bd9..0d6fa6e5e 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -6,6 +6,9 @@ fixtures: concat: 'https://github.com/puppetlabs/puppetlabs-concat' cron_core: 'https://github.com/puppetlabs/puppetlabs-cron_core' extlib: 'https://github.com/voxpupuli/puppet-extlib' + podman: + repo: 'https://github.com/evgeni/puppet-podman' + branch: 'quadlet' postgresql: 'https://github.com/puppetlabs/puppetlabs-postgresql' puppet: 'https://github.com/theforeman/puppet-puppet' redis: 'https://github.com/voxpupuli/puppet-redis' diff --git a/manifests/config.pp b/manifests/config.pp index 5007126f7..506285d9b 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -99,6 +99,7 @@ ) $min_puma_threads = pick($foreman::foreman_service_puma_threads_min, $foreman::foreman_service_puma_threads_max) systemd::dropin_file { 'foreman-service': + ensure => bool2str($foreman::deployment_mode == 'package', 'present', 'absent'), filename => 'installer.conf', unit => "${foreman::foreman_service}.service", content => template('foreman/foreman.service-overrides.erb'), @@ -153,7 +154,13 @@ } if $foreman::apache { - $listen_socket = '/run/foreman.sock' + if $foreman::deployment_mode == 'container' { + $listen_socket = 'localhost:3000/' + $backend_protocol = 'http' + } else { + $listen_socket = '/run/foreman.sock' + $backend_protocol = 'unix' + } class { 'foreman::config::apache': app_root => $foreman::app_root, @@ -162,7 +169,7 @@ serveraliases => $foreman::serveraliases, server_port => $foreman::server_port, server_ssl_port => $foreman::server_ssl_port, - proxy_backend => "unix://${listen_socket}", + proxy_backend => "${backend_protocol}://${listen_socket}", ssl => $foreman::ssl, ssl_ca => $foreman::server_ssl_ca, ssl_chain => $foreman::server_ssl_chain, @@ -281,7 +288,7 @@ } systemd::dropin_file { 'foreman-socket': - ensure => bool2str($foreman_socket_override =~ Undef, 'absent', 'present'), + ensure => bool2str($foreman_socket_override =~ Undef or $foreman::deployment_mode != 'package', 'absent', 'present'), filename => 'installer.conf', unit => "${foreman::foreman_service}.socket", content => $foreman_socket_override, diff --git a/manifests/init.pp b/manifests/init.pp index a3dde8393..cb52a90e5 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -189,6 +189,8 @@ # # $provisioning_fcct_location:: The location of the binary to call when transpiling Fedora CoreOS templates. # +# $deployment_mode:: The way foreman is deployed: packages or container +# # === Dynflow parameters: # # $dynflow_manage_services:: Whether to manage the dynflow services @@ -307,6 +309,7 @@ Boolean $register_in_foreman = true, Optional[Stdlib::Absolutepath] $provisioning_ct_location = undef, Optional[Stdlib::Absolutepath] $provisioning_fcct_location = undef, + Enum['package', 'container'] $deployment_mode = 'package', ) inherits foreman::params { assert_type(Array[Stdlib::IP::Address], $trusted_proxies) diff --git a/manifests/service.pp b/manifests/service.pp index 7e532bd80..2b87c8886 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -10,6 +10,8 @@ Enum['present', 'absent'] $dynflow_orchestrator_ensure = $foreman::dynflow_orchestrator_ensure, Integer[0] $dynflow_worker_instances = $foreman::dynflow_worker_instances, Integer[0] $dynflow_worker_concurrency = $foreman::dynflow_worker_concurrency, + Enum['package', 'container'] $deployment_mode = $foreman::deployment_mode, + String[1] $container_image = 'quay.io/evgeni/foreman-rpm:latest', ) { if $dynflow_manage_services { foreman::dynflow::worker { 'orchestrator': @@ -36,8 +38,8 @@ } service { "${foreman_service}.socket": - ensure => $foreman_service_ensure, - enable => $foreman_service_enable, + ensure => bool2str($deployment_mode == 'package', $foreman_service_ensure, 'stopped'), + enable => $foreman_service_enable and $deployment_mode == 'package', } service { $foreman_service: @@ -45,4 +47,34 @@ enable => $foreman_service_enable, before => Service["${foreman_service}.socket"], } + + if $deployment_mode == 'container' { + file { '/etc/containers/systemd': + ensure => directory, + } + File['/etc/containers/systemd/foreman.container'] ~> Service[$foreman_service] + Systemd::Daemon_reload['foreman.container'] ~> Service[$foreman_service] + } + + podman::quadlet { 'foreman.container': + ensure => bool2str($deployment_mode == 'container', 'present', 'absent'), + unit_entry => { + 'Description' => 'Foreman', + }, + service_entry => { + 'TimeoutStartSec' => '900', + }, + container_entry => { + 'Image' => $container_image, + 'Volume' => ['/etc/foreman/:/etc/foreman/'], + 'AddCapability' => ['CAP_DAC_OVERRIDE', 'CAP_IPC_OWNER'], + 'Network' => 'host', + 'HostName' => $foreman::servername, + 'Notify' => true, + }, + install_entry => { + 'WantedBy' => 'default.target', + }, + # don't set active true here, it makes podman::quadlet create a service that clashes with ours + } } diff --git a/metadata.json b/metadata.json index 04f1dc1b6..9de829d57 100644 --- a/metadata.json +++ b/metadata.json @@ -43,6 +43,10 @@ { "name": "puppet/redis", "version_requirement": ">= 5.0.0 < 12.0.0" + }, + { + "name": "southalc/podman", + "version_requirement": ">= 0.6.7 < 1.0.0" } ], "requirements": [ diff --git a/spec/acceptance/foreman_basic_spec.rb b/spec/acceptance/foreman_basic_spec.rb index 2655c0874..bf887dbe1 100644 --- a/spec/acceptance/foreman_basic_spec.rb +++ b/spec/acceptance/foreman_basic_spec.rb @@ -55,4 +55,24 @@ class { 'foreman': it_behaves_like 'the foreman application', { expected_login_url_path: '/users/extlogin' } end + + # needs to happen after GSSAPI, something is wrong with its cleanup + context 'in a Container' do + before(:context) { purge_foreman } + describe 'in a Container' do + it_behaves_like 'an idempotent resource' do + let(:manifest) do + <<~PUPPET + class { 'foreman': + deployment_mode => 'container', + db_host => 'localhost', + db_manage_rake => false, + } + PUPPET + end + end + + it_behaves_like 'the foreman application', { deployment_mode: 'container' } + end + end end diff --git a/spec/support/acceptance/examples.rb b/spec/support/acceptance/examples.rb index bcb8bd398..2b17b6975 100644 --- a/spec/support/acceptance/examples.rb +++ b/spec/support/acceptance/examples.rb @@ -19,8 +19,10 @@ it { is_expected.to be_listening } end - describe file('/run/foreman.sock') do - it { should be_socket } + if params.fetch(:deployment_mode, 'package') == 'package' + describe file('/run/foreman.sock') do + it { should be_socket } + end end describe command("curl -s --cacert /etc/foreman-certs/certificate.pem https://#{host_inventory['fqdn']} -w '\%{redirect_url}' -o /dev/null") do diff --git a/spec/support/acceptance/purge.rb b/spec/support/acceptance/purge.rb index 7522048b1..fa1943000 100644 --- a/spec/support/acceptance/purge.rb +++ b/spec/support/acceptance/purge.rb @@ -6,6 +6,7 @@ def purge_foreman on default, 'apt-get purge -y foreman*', { :acceptable_exit_codes => [0, 100] } on default, 'apt-get purge -y ruby-hammer-cli-*', { :acceptable_exit_codes => [0, 100] } end + on default, 'rm -rf /etc/systemd/system/foreman* /etc/containers/systemd/foreman*' apache_service_name = ['debian', 'ubuntu'].include?(os[:family]) ? 'apache2' : 'httpd' on default, "systemctl stop #{apache_service_name}", { :acceptable_exit_codes => [0, 5] }