Add support for live-migration over SSH

Change-Id: Iac1763761c652bed637cb7cf85bc12347b5fe7ec
This commit is contained in:
Oliver Walsh 2017-03-30 21:23:07 +01:00 committed by Juan Antonio Osorio Robles
parent 0217cb3511
commit d3b953cdd9
3 changed files with 180 additions and 33 deletions

View File

@ -4,9 +4,10 @@
# #
# === Parameters: # === Parameters:
# #
# [*use_tls*] # [*transport*]
# (optional) Use tls for remote connections to libvirt # (optional) Transport to use for live-migration.
# Defaults to false # Valid options are 'tcp', 'tls', and 'ssh'.
# Defaults to 'tcp'
# #
# [*auth*] # [*auth*]
# (optional) Use this authentication scheme for remote libvirt connections. # (optional) Use this authentication scheme for remote libvirt connections.
@ -53,8 +54,29 @@
# (optional) Whether or not configure libvirt bits. # (optional) Whether or not configure libvirt bits.
# Defaults to true. # Defaults to true.
# #
# [*client_user*]
# (optional) Remote user to connect as.
# Only applies to ssh transport.
# Defaults to undef (root)
#
# [*client_port*]
# (optional) Remote port to connect to.
# Defaults to undef (default port for the transport)
#
# [*client_extraparams*]
# (optional) Hash of additional params to append to the live-migraition uri
# See https://libvirt.org/guide/html/Application_Development_Guide-Architecture-Remote_URIs.html
# Defaults to {}
#
# DEPRECATED PARAMETERS
#
# [*use_tls*]
# (optional) Use tls for remote connections to libvirt
# Defaults to false
# Deprecated by transport paramater.
#
class nova::migration::libvirt( class nova::migration::libvirt(
$use_tls = false, $transport = undef,
$auth = 'none', $auth = 'none',
$listen_address = undef, $listen_address = undef,
$live_migration_tunnelled = $::os_service_default, $live_migration_tunnelled = $::os_service_default,
@ -63,28 +85,70 @@ class nova::migration::libvirt(
$override_uuid = false, $override_uuid = false,
$configure_libvirt = true, $configure_libvirt = true,
$configure_nova = true, $configure_nova = true,
$client_user = undef,
$client_port = undef,
$client_extraparams = {},
# DEPRECATED PARAMETERS
$use_tls = false,
){ ){
include ::nova::deps include ::nova::deps
if $transport {
$transport_real = $transport
} elsif $use_tls {
warning(
'The use_tls parameter is now deprecated and will be removed in the Queens cycle. Please set transport=tls instead.'
)
$transport_real = 'tls'
} else {
$transport_real = 'tcp'
}
validate_re($transport_real, ['^tcp$', '^tls$', '^ssh$'], 'Valid options for transport are tcp, tls, ssh.')
validate_re($auth, [ '^sasl$', '^none$' ], 'Valid options for auth are none and sasl.') validate_re($auth, [ '^sasl$', '^none$' ], 'Valid options for auth are none and sasl.')
if $use_tls { if $transport_real == 'tls' {
$listen_tls = '1' $listen_tls = '1'
$listen_tcp = '0' $listen_tcp = '0'
} else { } elsif $transport_real == 'tcp' {
$listen_tls = '0' $listen_tls = '0'
$listen_tcp = '1' $listen_tcp = '1'
} else {
$listen_tls = '0'
$listen_tcp = '0'
} }
if $configure_nova { if $configure_nova {
if $use_tls {
nova_config { if $transport_real == 'ssh' {
'libvirt/live_migration_uri': value => 'qemu+tls://%s/system'; if $client_user {
$prefix = "${client_user}@"
} else {
$prefix = ''
} }
} else {
$prefix = ''
} }
if $client_port {
$postfix = ":${client_port}"
} else {
$postfix = ''
}
if $client_extraparams != {} {
$extra_params_before_python_escape = join(uriescape(join_keys_to_values($client_extraparams, '=')), '&')
# Must escape % as nova interprets it incorrecly.
$extra_params = sprintf('?%s', regsubst($extra_params_before_python_escape, '%', '%%', 'G'))
} else {
$extra_params =''
}
$live_migration_uri = "qemu+${transport_real}://${prefix}%s${postfix}/system${extra_params}"
nova_config { nova_config {
'libvirt/live_migration_uri': value => $live_migration_uri;
'libvirt/live_migration_tunnelled': value => $live_migration_tunnelled; 'libvirt/live_migration_tunnelled': value => $live_migration_tunnelled;
'libvirt/live_migration_completion_timeout': value => $live_migration_completion_timeout; 'libvirt/live_migration_completion_timeout': value => $live_migration_completion_timeout;
'libvirt/live_migration_progress_timeout': value => $live_migration_progress_timeout; 'libvirt/live_migration_progress_timeout': value => $live_migration_progress_timeout;
@ -136,14 +200,14 @@ class nova::migration::libvirt(
tag => 'libvirt-file_line', tag => 'libvirt-file_line',
} }
if $use_tls { if $transport_real == 'tls' {
file_line { '/etc/libvirt/libvirtd.conf auth_tls': file_line { '/etc/libvirt/libvirtd.conf auth_tls':
path => '/etc/libvirt/libvirtd.conf', path => '/etc/libvirt/libvirtd.conf',
line => "auth_tls = \"${auth}\"", line => "auth_tls = \"${auth}\"",
match => 'auth_tls =', match => 'auth_tls =',
tag => 'libvirt-file_line', tag => 'libvirt-file_line',
} }
} else { } elsif $transport_real == 'tcp' {
file_line { '/etc/libvirt/libvirtd.conf auth_tcp': file_line { '/etc/libvirt/libvirtd.conf auth_tcp':
path => '/etc/libvirt/libvirtd.conf', path => '/etc/libvirt/libvirtd.conf',
line => "auth_tcp = \"${auth}\"", line => "auth_tcp = \"${auth}\"",
@ -161,11 +225,13 @@ class nova::migration::libvirt(
} }
} }
file_line { '/etc/sysconfig/libvirtd libvirtd args': if $transport_real != 'ssh' {
path => '/etc/sysconfig/libvirtd', file_line { '/etc/sysconfig/libvirtd libvirtd args':
line => 'LIBVIRTD_ARGS="--listen"', path => '/etc/sysconfig/libvirtd',
match => 'LIBVIRTD_ARGS=', line => 'LIBVIRTD_ARGS="--listen"',
tag => 'libvirt-file_line', match => 'LIBVIRTD_ARGS=',
tag => 'libvirt-file_line',
}
} }
} }
@ -184,14 +250,14 @@ class nova::migration::libvirt(
tag => 'libvirt-file_line', tag => 'libvirt-file_line',
} }
if $use_tls { if $transport_real == 'tls' {
file_line { '/etc/libvirt/libvirtd.conf auth_tls': file_line { '/etc/libvirt/libvirtd.conf auth_tls':
path => '/etc/libvirt/libvirtd.conf', path => '/etc/libvirt/libvirtd.conf',
line => "auth_tls = \"${auth}\"", line => "auth_tls = \"${auth}\"",
match => 'auth_tls =', match => 'auth_tls =',
tag => 'libvirt-file_line', tag => 'libvirt-file_line',
} }
} else { } elsif $transport_real == 'tcp' {
file_line { '/etc/libvirt/libvirtd.conf auth_tcp': file_line { '/etc/libvirt/libvirtd.conf auth_tcp':
path => '/etc/libvirt/libvirtd.conf', path => '/etc/libvirt/libvirtd.conf',
line => "auth_tcp = \"${auth}\"", line => "auth_tcp = \"${auth}\"",
@ -209,19 +275,21 @@ class nova::migration::libvirt(
} }
} }
if $::operatingsystem == 'Ubuntu' and versioncmp($::operatingsystemmajrelease, '16') >= 0 { if $transport_real != 'ssh' {
# If systemd is being used then libvirtd is already being launched correctly and if $::operatingsystem == 'Ubuntu' and versioncmp($::operatingsystemmajrelease, '16') >= 0 {
# adding -d causes a second consecutive start to fail which causes puppet to fail. # If systemd is being used then libvirtd is already being launched correctly and
$libvirtd_opts = 'libvirtd_opts="-l"' # adding -d causes a second consecutive start to fail which causes puppet to fail.
} else { $libvirtd_opts = 'libvirtd_opts="-l"'
$libvirtd_opts = 'libvirtd_opts="-d -l"' } else {
} $libvirtd_opts = 'libvirtd_opts="-d -l"'
}
file_line { "/etc/default/${::nova::compute::libvirt::libvirt_service_name} libvirtd opts": file_line { "/etc/default/${::nova::compute::libvirt::libvirt_service_name} libvirtd opts":
path => "/etc/default/${::nova::compute::libvirt::libvirt_service_name}", path => "/etc/default/${::nova::compute::libvirt::libvirt_service_name}",
line => $libvirtd_opts, line => $libvirtd_opts,
match => 'libvirtd_opts=', match => 'libvirtd_opts=',
tag => 'libvirt-file_line', tag => 'libvirt-file_line',
}
} }
} }

View File

@ -0,0 +1,13 @@
---
features:
- |
Add support for libvirt live-migration over SSH including the ability to
override all libvirt options applicable to the SSH transport.
For more info see https://libvirt.org/remote.html#Remote_URI_reference.
Adds new parameter "nova::migration::libvirt::transport"
Adds new parameter "nova::migration::libvirt::client_user"
Adds new parameter "nova::migration::libvirt::client_port"
Adds new parameter "nova::migration::libvirt::client_extraparams"
deprecations:
- |
The "nova::migration::libvirt::use_tls" parameter is deprecated by the "nova::migration::libvirt::transport" parameter.

View File

@ -47,6 +47,8 @@ describe 'nova::migration::libvirt' do
it { is_expected.to contain_nova_config('libvirt/live_migration_tunnelled').with_value('<SERVICE DEFAULT>') } it { is_expected.to contain_nova_config('libvirt/live_migration_tunnelled').with_value('<SERVICE DEFAULT>') }
it { is_expected.to contain_nova_config('libvirt/live_migration_completion_timeout').with_value('<SERVICE DEFAULT>') } it { is_expected.to contain_nova_config('libvirt/live_migration_completion_timeout').with_value('<SERVICE DEFAULT>') }
it { is_expected.to contain_nova_config('libvirt/live_migration_progress_timeout').with_value('<SERVICE DEFAULT>') } it { is_expected.to contain_nova_config('libvirt/live_migration_progress_timeout').with_value('<SERVICE DEFAULT>') }
it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+tcp://%s/system') }
end end
context 'with override_uuid enabled' do context 'with override_uuid enabled' do
@ -66,7 +68,7 @@ describe 'nova::migration::libvirt' do
}).that_requires('Package[libvirt]').that_notifies('Service[libvirt]') } }).that_requires('Package[libvirt]').that_notifies('Service[libvirt]') }
end end
context 'with tls enabled' do context 'with tls enabled (legacy)' do
let :params do let :params do
{ {
:use_tls => true, :use_tls => true,
@ -79,6 +81,19 @@ describe 'nova::migration::libvirt' do
it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+tls://%s/system')} it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+tls://%s/system')}
end end
context 'with tls enabled' do
let :params do
{
:transport => 'tls',
}
end
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tls').with(:line => "listen_tls = 1") }
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tcp').with(:line => "listen_tcp = 0") }
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf auth_tls').with(:line => "auth_tls = \"none\"") }
it { is_expected.not_to contain_file_line('/etc/libvirt/libvirtd.conf auth_tcp')}
it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+tls://%s/system')}
end
context 'with migration flags set' do context 'with migration flags set' do
let :params do let :params do
{ {
@ -106,7 +121,7 @@ describe 'nova::migration::libvirt' do
let :params do let :params do
{ {
:auth => 'sasl', :auth => 'sasl',
:use_tls => true :transport => 'tls'
} }
end end
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf auth_tls').with(:line => "auth_tls = \"sasl\"") } it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf auth_tls').with(:line => "auth_tls = \"sasl\"") }
@ -130,13 +145,14 @@ describe 'nova::migration::libvirt' do
} }
end end
it { is_expected.not_to contain_file_line('/etc/libvirt/libvirtd.conf listen_tls') } it { is_expected.not_to contain_file_line('/etc/libvirt/libvirtd.conf listen_tls') }
it { is_expected.not_to contain_file_line('/etc/libvirt/libvirtd.conf listen_tcp') }
end end
context 'when not configuring nova and tls enabled' do context 'when not configuring nova and tls enabled' do
let :params do let :params do
{ {
:configure_nova => false, :configure_nova => false,
:use_tls => true, :transport => 'tls',
} }
end end
it { is_expected.not_to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+tls://%s/system') } it { is_expected.not_to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+tls://%s/system') }
@ -192,4 +208,54 @@ describe 'nova::migration::libvirt' do
it { is_expected.to contain_file_line('/etc/sysconfig/libvirtd libvirtd args').with(:line => 'LIBVIRTD_ARGS="--listen"') } it { is_expected.to contain_file_line('/etc/sysconfig/libvirtd libvirtd args').with(:line => 'LIBVIRTD_ARGS="--listen"') }
end end
shared_examples_for 'ssh tunneling' do
context 'with ssh transport' do
let :params do
{
:transport => 'ssh',
}
end
it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+ssh://%s/system')}
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tls').with(:line => "listen_tls = 0") }
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tcp').with(:line => "listen_tcp = 0") }
end
context 'with ssh transport with user' do
let :params do
{
:transport => 'ssh',
:client_user => 'foobar'
}
end
it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+ssh://foobar@%s/system')}
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tls').with(:line => "listen_tls = 0") }
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tcp').with(:line => "listen_tcp = 0") }
end
context 'with ssh transport with port' do
let :params do
{
:transport => 'ssh',
:client_port => 1234
}
end
it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+ssh://%s:1234/system')}
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tls').with(:line => "listen_tls = 0") }
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tcp').with(:line => "listen_tcp = 0") }
end
context 'with ssh transport with extraparams' do
let :params do
{
:transport => 'ssh',
:client_extraparams => {'foo' => '%', 'bar' => 'baz'}
}
end
it { is_expected.to contain_nova_config('libvirt/live_migration_uri').with_value('qemu+ssh://%s/system?foo=%%25&bar=baz')}
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tls').with(:line => "listen_tls = 0") }
it { is_expected.to contain_file_line('/etc/libvirt/libvirtd.conf listen_tcp').with(:line => "listen_tcp = 0") }
end
end
end end