From 46bc83f643fc27805a20d592c707bfd3c2287236 Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Tue, 14 May 2024 11:29:28 +0200 Subject: [PATCH 1/4] run foreman in a container --- .fixtures.yml | 3 ++ manifests/config.pp | 36 +++++++++++++-------- manifests/init.pp | 3 ++ manifests/service.pp | 45 ++++++++++++++++++++++----- metadata.json | 4 +++ spec/acceptance/foreman_basic_spec.rb | 20 ++++++++++++ spec/support/acceptance/examples.rb | 6 ++-- spec/support/acceptance/purge.rb | 1 + 8 files changed, 95 insertions(+), 23 deletions(-) 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..1149fbaf3 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -98,11 +98,13 @@ ) ) $min_puma_threads = pick($foreman::foreman_service_puma_threads_min, $foreman::foreman_service_puma_threads_max) - systemd::dropin_file { 'foreman-service': - filename => 'installer.conf', - unit => "${foreman::foreman_service}.service", - content => template('foreman/foreman.service-overrides.erb'), - notify_service => true, + if $foreman::deployment_mode == 'package' { + systemd::dropin_file { 'foreman-service': + filename => 'installer.conf', + unit => "${foreman::foreman_service}.service", + content => template('foreman/foreman.service-overrides.erb'), + notify_service => true, + } } if ! defined(File[$foreman::app_root]) { @@ -153,7 +155,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 +170,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, @@ -280,11 +288,13 @@ $foreman_socket_override = undef } - systemd::dropin_file { 'foreman-socket': - ensure => bool2str($foreman_socket_override =~ Undef, 'absent', 'present'), - filename => 'installer.conf', - unit => "${foreman::foreman_service}.socket", - content => $foreman_socket_override, - notify_service => true, + if $foreman::deployment_mode == 'package' { + systemd::dropin_file { 'foreman-socket': + ensure => bool2str($foreman_socket_override =~ Undef, 'absent', 'present'), + filename => 'installer.conf', + unit => "${foreman::foreman_service}.socket", + content => $foreman_socket_override, + notify_service => true, + } } } 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..d63ad74ca 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': @@ -35,14 +37,41 @@ } } - service { "${foreman_service}.socket": - ensure => $foreman_service_ensure, - enable => $foreman_service_enable, - } + if $deployment_mode == 'package' { + service { "${foreman_service}.socket": + ensure => $foreman_service_ensure, + enable => $foreman_service_enable, + } - service { $foreman_service: - ensure => $foreman_service_ensure, - enable => $foreman_service_enable, - before => Service["${foreman_service}.socket"], + service { $foreman_service: + ensure => $foreman_service_ensure, + enable => $foreman_service_enable, + before => Service["${foreman_service}.socket"], + } + } else { + file { '/etc/containers/systemd': + ensure => directory, + } + podman::quadlet { 'foreman.container': + ensure => present, + 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', + }, + active => true, + } } } 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] } From 1ecc0dfb6afd560a7a61250e1e186d7586430458 Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Tue, 21 May 2024 12:24:50 +0200 Subject: [PATCH 2/4] ensure! --- manifests/config.pp | 27 +++++++++---------- manifests/service.pp | 62 ++++++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/manifests/config.pp b/manifests/config.pp index 1149fbaf3..506285d9b 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -98,13 +98,12 @@ ) ) $min_puma_threads = pick($foreman::foreman_service_puma_threads_min, $foreman::foreman_service_puma_threads_max) - if $foreman::deployment_mode == 'package' { - systemd::dropin_file { 'foreman-service': - filename => 'installer.conf', - unit => "${foreman::foreman_service}.service", - content => template('foreman/foreman.service-overrides.erb'), - notify_service => true, - } + 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'), + notify_service => true, } if ! defined(File[$foreman::app_root]) { @@ -288,13 +287,11 @@ $foreman_socket_override = undef } - if $foreman::deployment_mode == 'package' { - systemd::dropin_file { 'foreman-socket': - ensure => bool2str($foreman_socket_override =~ Undef, 'absent', 'present'), - filename => 'installer.conf', - unit => "${foreman::foreman_service}.socket", - content => $foreman_socket_override, - notify_service => true, - } + systemd::dropin_file { 'foreman-socket': + 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, + notify_service => true, } } diff --git a/manifests/service.pp b/manifests/service.pp index d63ad74ca..527d13000 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -37,41 +37,47 @@ } } - if $deployment_mode == 'package' { - service { "${foreman_service}.socket": - ensure => $foreman_service_ensure, - enable => $foreman_service_enable, - } + service { "${foreman_service}.socket": + ensure => bool2str($deployment_mode == 'package', $foreman_service_ensure, 'stopped'), + enable => bool2str($deployment_mode == 'package', $foreman_service_enable, 'false'), + } - service { $foreman_service: + if $deployment_mode == 'package' { + # podman::quadlet already creates a service with the same name + service { "${foreman_service}.service": ensure => $foreman_service_ensure, enable => $foreman_service_enable, before => Service["${foreman_service}.socket"], } - } else { + } + + if $deployment_mode == 'container' { file { '/etc/containers/systemd': ensure => directory, } - podman::quadlet { 'foreman.container': - ensure => present, - 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', - }, - active => true, - } + } + + $quadlet_active = $deployment_mode ? { 'container' => true, default => undef } + + 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', + }, + active => $quadlet_active, } } From 26de9dcc8ad305d60dcb421bc5f0fdad8226f84b Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Tue, 21 May 2024 13:51:35 +0200 Subject: [PATCH 3/4] don't use active true, it does more harm than it's useful --- manifests/service.pp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/manifests/service.pp b/manifests/service.pp index 527d13000..0a071e9d2 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -42,23 +42,20 @@ enable => bool2str($deployment_mode == 'package', $foreman_service_enable, 'false'), } - if $deployment_mode == 'package' { - # podman::quadlet already creates a service with the same name - service { "${foreman_service}.service": - ensure => $foreman_service_ensure, - enable => $foreman_service_enable, - before => Service["${foreman_service}.socket"], - } + service { $foreman_service: + ensure => $foreman_service_ensure, + 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] } - $quadlet_active = $deployment_mode ? { 'container' => true, default => undef } - podman::quadlet { 'foreman.container': ensure => bool2str($deployment_mode == 'container', 'present', 'absent'), unit_entry => { @@ -78,6 +75,6 @@ install_entry => { 'WantedBy' => 'default.target', }, - active => $quadlet_active, + # don't set active true here, it makes podman::quadlet create a service that clashes with ours } } From 3084d7dfd9148c8b9402b16d3bbae3d0c2f2feea Mon Sep 17 00:00:00 2001 From: Evgeni Golov Date: Tue, 21 May 2024 14:18:21 +0200 Subject: [PATCH 4/4] lol --- manifests/service.pp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifests/service.pp b/manifests/service.pp index 0a071e9d2..2b87c8886 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -39,7 +39,7 @@ service { "${foreman_service}.socket": ensure => bool2str($deployment_mode == 'package', $foreman_service_ensure, 'stopped'), - enable => bool2str($deployment_mode == 'package', $foreman_service_enable, 'false'), + enable => $foreman_service_enable and $deployment_mode == 'package', } service { $foreman_service: