8000 run foreman in a container by evgeni · Pull Request #1164 · theforeman/puppet-foreman · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

run foreman in a container #1164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for 8000 GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
13 changes: 10 additions & 3 deletions manifests/config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
)
$min_puma_threads = pick($foreman::foreman_service_puma_threads_min, $foreman::foreman_service_pu 8000 ma_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'),
Expand Down Expand Up @@ -153,7 +154,13 @@
}

if $foreman::apache {
$listen_socket = '/run/foreman.sock'
if $foreman::deployment_mode == 'container' {
$listen_socket = 'localhost:3000/'
Copy link
Member Author

Choose a reason for hiding this comment

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

This one was tricky. Apache (or foreman::config::apache) doesn't add a trailing slash to the backend, which then tries to access things like http://localhost:3000users/login, obviously failing

Copy link
Member

Choose a reason for hiding this comment

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

You can use systemd socket activation with podman containers. I've used that myself with gunicorn to avoid needing to deal with a firewall (and instead deal with SELinux). Any reason you don't use that now?

See https://github.com/containers/podman/blob/main/docs/tutorials/socket_activation.md#socket-activation-of-containers for more info.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh cool. I didn't try that (yet), but I also think that the above is a legit bug in our current deployment if for some reason users do not want sockets.

also lol @ "and instead deal with SELinux" ;)

Copy link
Member

Choose a reason for hiding this comment

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

Quite possible that there's a bug there

$backend_protocol = 'http'
} else {
$listen_socket = '/run/foreman.sock'
$backend_protocol = 'unix'
}

class { 'foreman::config::apache':
app_root => $foreman::app_root,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down
36 changes: 34 additions & 2 deletions manifests/service.pp
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand All @@ -36,13 +38,43 @@
}

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:
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]
}

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
}
}
4 changes: 4 additions & 0 deletions metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
Expand Down
20 changes: 20 additions & 0 deletions spec/acceptance/foreman_basic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Comment on lines +68 to +69
Copy link
Member Author

Choose a reason for hiding this comment

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

I wonder if these two could be made more "dynamic"?

Copy link
Member

Choose a reason for hiding this comment

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

What do you mean? That db_manage_rake would be undef by default and the deployment mode determines the value?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, same for host (there is not really a socket in the container)

}
PUPPET
end
end

it_behaves_like 'the foreman application', { deployment_mode: 'container' }
end
end
end
6 changes: 4 additions & 2 deletions spec/support/acceptance/examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions spec/support/acceptance/purge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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] }
Expand Down
0