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..d501a6428 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] }