From e9b881647a99de801660e262972dbe711999a239 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Sat, 25 Mar 2023 00:38:06 +0900 Subject: [PATCH] Make sure socket listens on specific interface This change makes sure that systemd sockets for libvirt/virtproxy listen on a specific interface instead of all interfaces, when user gives the listen_address parameter. Closes-Bug: #2012747 Change-Id: I8e7775ce73eeb44a60dc94de1c1707aec92f6ae3 --- manifests/migration/libvirt.pp | 73 +++++++++++++++++-- .../notes/bug-2012747-36e40b85697e7eb7.yaml | 5 ++ spec/classes/nova_migration_libvirt_spec.rb | 38 +++++++++- 3 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 releasenotes/notes/bug-2012747-36e40b85697e7eb7.yaml diff --git a/manifests/migration/libvirt.pp b/manifests/migration/libvirt.pp index ea582f94d..274157ad4 100644 --- a/manifests/migration/libvirt.pp +++ b/manifests/migration/libvirt.pp @@ -331,21 +331,78 @@ class nova::migration::libvirt( true => 'virtproxyd', default => 'libvirtd', } - # libvirtd.service should be stopped before socket service is started. - # Otherwise, socket service fails to start. - exec { "stop ${proxy_service}.service": + $socket_name = "${proxy_service}-${transport_real}" + + # This is the dummy resource to trigger exec to stop libvirtd.service. + # libvirtd.service should be stopped before socket is started. + # Otherwise, socket fails to start. + exec { "check ${socket_name}.socket": + command => '/usr/bin/true', path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'], - command => "systemctl -q stop ${proxy_service}.service", - unless => "systemctl -q is-active ${proxy_service}-${transport_real}.socket", - require => Anchor['nova::install::end'] + unless => "systemctl -q is-active ${socket_name}.socket", + require => Anchor['nova::config::end'] } - -> service { "${proxy_service}-${transport_real}": + + exec { "stop ${proxy_service}.service": + command => "systemctl -q stop ${proxy_service}.service", + path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'], + refreshonly => true, + require => Anchor['nova::install::end'] + } + + service { $socket_name: ensure => 'running', - name => "${proxy_service}-${transport_real}.socket", + name => "${socket_name}.socket", enable => true, require => Anchor['nova::config::end'] } + Exec["check ${socket_name}.socket"] + ~> Exec["stop ${proxy_service}.service"] + -> Service[$socket_name] + + if is_service_default($listen_address) { + file { "/etc/systemd/system/${socket_name}.socket": + ensure => absent, + require => Anchor['nova::install::end'] + } ~> exec { 'systemd-damon-reload': + command => 'systemctl daemon-reload', + path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'], + refreshonly => true, + } ~> Service[$socket_name] + + } else { + $listen_address_real = normalize_ip_for_uri($listen_address) + + $default_listen_port = $transport_real ? { + 'tls' => 16514, + default => 16509 + } + $listen_port = pick($client_port, $default_listen_port) + + # TODO(tkajinam): We have to completely override the socket file, + # because dropin does not allow us to remove + # ListenStream in the base file. + exec { "create ${socket_name}.socket": + command => "cp /usr/lib/systemd/system/${socket_name}.socket /etc/systemd/system/", + path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'], + creates => "/etc/systemd/system/${socket_name}.socket", + require => Anchor['nova::install::end'], + } -> file_line { "${proxy_service}-${transport_real}.socket ListenStream": + path => "/etc/systemd/system/${socket_name}.socket", + line => "ListenStream=${listen_address_real}:${listen_port}", + match => '^ListenStream=.*', + } ~> exec { 'systemd-damon-reload': + command => 'systemctl daemon-reload', + path => ['/sbin', '/usr/sbin', '/bin', '/usr/bin'], + refreshonly => true, + } ~> Service[$socket_name] + Exec["create ${socket_name}.socket"] ~> Exec['systemd-damon-reload'] + } + + # We have to stop libvirtd.service to restart socket. + Exec['systemd-damon-reload'] ~> Exec["stop ${proxy_service}.service"] + if $modular_libvirt { Service["${proxy_service}-${transport_real}"] -> Service<| title == 'virtproxyd' |> } else { diff --git a/releasenotes/notes/bug-2012747-36e40b85697e7eb7.yaml b/releasenotes/notes/bug-2012747-36e40b85697e7eb7.yaml new file mode 100644 index 000000000..6d9629d69 --- /dev/null +++ b/releasenotes/notes/bug-2012747-36e40b85697e7eb7.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Now ``nova::migration::libvirt`` ensures that tcp/tls socket listens on + a specific interface when the `listen_address` parameter is used. diff --git a/spec/classes/nova_migration_libvirt_spec.rb b/spec/classes/nova_migration_libvirt_spec.rb index 9902309f6..743fab71f 100644 --- a/spec/classes/nova_migration_libvirt_spec.rb +++ b/spec/classes/nova_migration_libvirt_spec.rb @@ -442,7 +442,10 @@ describe 'nova::migration::libvirt' do :name => 'libvirtd-tls.socket', :ensure => 'running', :enable => true, - )} + )} + it { is_expected.to contain_file('/etc/systemd/system/libvirtd-tls.socket').with( + :ensure => 'absent', + )} end context 'with tcp transport' do @@ -460,7 +463,10 @@ describe 'nova::migration::libvirt' do :name => 'libvirtd-tcp.socket', :ensure => 'running', :enable => true, - )} + )} + it { is_expected.to contain_file('/etc/systemd/system/libvirtd-tcp.socket').with( + :ensure => 'absent', + )} end context 'with tls transport and modular daemons' do @@ -476,6 +482,9 @@ describe 'nova::migration::libvirt' do :ensure => 'running', :enable => true, )} + it { is_expected.to contain_file('/etc/systemd/system/virtproxyd-tls.socket').with( + :ensure => 'absent', + )} end context 'with tcp transport and modular daemons' do @@ -491,6 +500,9 @@ describe 'nova::migration::libvirt' do :ensure => 'running', :enable => true, )} + it { is_expected.to contain_file('/etc/systemd/system/virtproxyd-tcp.socket').with( + :ensure => 'absent', + )} end end @@ -510,11 +522,17 @@ describe 'nova::migration::libvirt' do :ensure => 'running', :enable => true, )} + it { is_expected.to contain_file('/etc/systemd/system/libvirtd-tls.socket').with( + :ensure => 'absent', + )} end context 'with tcp transport' do let :params do - { :transport => 'tcp' } + { + :transport => 'tcp', + :listen_address => '127.0.0.1' + } end it { is_expected.to contain_file('/etc/sysconfig/libvirtd').with( @@ -527,6 +545,11 @@ describe 'nova::migration::libvirt' do :ensure => 'running', :enable => true, )} + it { is_expected.to contain_file_line('libvirtd-tcp.socket ListenStream').with( + :path => '/etc/systemd/system/libvirtd-tcp.socket', + :line => 'ListenStream=127.0.0.1:16509', + :match => '^ListenStream=.*', + )} end context 'with tls transport and modular daemons' do @@ -534,6 +557,7 @@ describe 'nova::migration::libvirt' do { :transport => 'tls', :modular_libvirt => true, + :listen_address => '::1' } end @@ -542,6 +566,11 @@ describe 'nova::migration::libvirt' do :ensure => 'running', :enable => true, )} + it { is_expected.to contain_file_line('virtproxyd-tls.socket ListenStream').with( + :path => '/etc/systemd/system/virtproxyd-tls.socket', + :line => 'ListenStream=[::1]:16514', + :match => '^ListenStream=.*', + )} end context 'with tcp transport and modular daemons' do @@ -557,6 +586,9 @@ describe 'nova::migration::libvirt' do :ensure => 'running', :enable => true, )} + it { is_expected.to contain_file('/etc/systemd/system/virtproxyd-tcp.socket').with( + :ensure => 'absent', + )} end end