[Newton only] Do not overwrite current {neutron,nova}::host value.
In newton we are setting both nova::host and neutron::host values explicitly to the fqdn. This can cause problem during upgrade from Mitaka. The previous host value (defaulting to python socket.gethostname) could return only the hostname[0]. It means that during upgrade we are changing this identifier. At restart nova/neutron creates *new* agents. Those agents are then unaware of existing workload. For neutron, the problem is that due to [1] and the fact the L3 agents are in HA mode, the previous defined workloads on those agent get lost and FIPs become unreachable. For nova it's no longer possible to send commands to (before upgrade) existing vm anymore. This patch checks the current live value of the host parameter through a fact and set the nova::host and neutron::host value to it if we are not in a deployment (upgrade/update) For nova, we directly use nova-manage to get the current live value. Using the mysql parameter directly has the advantage that it's defined on all types of node (controller *and* compute). As a matter of fact the required auth parameters are usually not defined on compute node. For neutron, when auth is available in the configuration (on Controller) we use that. There is no neutron-manage equivalent here so we use the nova value when auth is unavailable. When host is unset they both use python.gethostname, so it should be the same value. Using auth on controller add another level of confidence though. And the controller are where the l3 agents are, so better be safe than sorry. This patch is newton only as it's where we are setting for the first time this parameter. After that (ocata on) we use[2] to make sure that those parameters are never rewritten. [0] https://bugzilla.redhat.com/show_bug.cgi?id=1499201 [1] https://review.openstack.org/#/c/560855/ [2] need to be backported to ocata https://review.openstack.org/#/q/I8f075a5ad869ef0dc72a700dcb7be0b6efca787a Partial-Bug: #1763322 Change-Id: Ieb92ff161d1684c214382c5eb6b5949efc3fe75c
This commit is contained in:
parent
f6d398a7da
commit
6938b5d1f2
|
@ -0,0 +1,64 @@
|
|||
def get_auth(component)
|
||||
provider = Object.const_get "Puppet::Provider::#{component.capitalize}"
|
||||
auth_func = "#{component}_credentials"
|
||||
if provider.respond_to?(auth_func)
|
||||
begin
|
||||
q = provider.send(auth_func)
|
||||
rescue Puppet::Error
|
||||
q = {}
|
||||
end
|
||||
authenv = {
|
||||
'OS_AUTH_URL' => q['auth_url'],
|
||||
'OS_USERNAME' => q['username'],
|
||||
'OS_PROJECT_NAME' => q['project_name'],
|
||||
'OS_PASSWORD' => q['password']
|
||||
}
|
||||
if q.key?('region_name')
|
||||
authenv['OS_REGION_NAME'] = q['region_name']
|
||||
end
|
||||
authenv
|
||||
end
|
||||
end
|
||||
|
||||
def get_live_value_from_auth(component)
|
||||
# The path is correct for this tripleo version.
|
||||
provider_file = "/etc/puppet/modules/#{component}/lib/puppet/provider/#{component}.rb"
|
||||
if File.exists?(provider_file)
|
||||
require_relative(provider_file)
|
||||
auth_env = get_auth(component)
|
||||
host = if auth_env
|
||||
Facter::Core::Execution.with_env(auth_env) do
|
||||
# We want to find if the current host value is the fqdn
|
||||
# or the hostname. We are sure that it will be at
|
||||
# least the hostname so the grep will work.
|
||||
Facter::Core::Execution.execute(
|
||||
"#{component} agent-list -c host -f value 2>/dev/null | grep #{Facter.value(:hostname)} 2>/dev/null",
|
||||
{:on_fail => ''}
|
||||
).split("\n").first
|
||||
end
|
||||
end
|
||||
host || ''
|
||||
end
|
||||
end
|
||||
|
||||
def get_nova_live_value
|
||||
Tempfile.open('get-nova-host') do |nova_stdin|
|
||||
File.open(nova_stdin, 'w') do |nova_cmd|
|
||||
nova_cmd.puts("import nova.conf\nprint nova.conf.CONF.host")
|
||||
end
|
||||
Facter::Core::Execution.execute("nova-manage shell python 2>/dev/null < #{nova_stdin} | sed -e 's/^[> ]*//'")
|
||||
end
|
||||
end
|
||||
|
||||
['nova', 'neutron'].each do |component|
|
||||
Facter.add("current_#{component}_host") do
|
||||
confine kernel: 'Linux'
|
||||
setcode do
|
||||
if component == 'nova'
|
||||
get_nova_live_value.strip
|
||||
else
|
||||
get_live_value_from_auth(component).strip
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -63,8 +63,25 @@ class tripleo::profile::base::neutron (
|
|||
elsif $dhcp_agent_count > 0 {
|
||||
$dhcp_agents_per_net = $dhcp_agent_count
|
||||
}
|
||||
if hiera('stack_action', undef) == 'UPDATE' {
|
||||
if !empty($::current_neutron_host) {
|
||||
$host_real = $::current_neutron_host
|
||||
}
|
||||
# Try nova value as we could be on a compute node without all
|
||||
# the necessary neutron definition. The host value will be identical.
|
||||
elsif !empty($::current_nova_host) {
|
||||
$host_real = $::current_nova_host
|
||||
} else {
|
||||
# We fail instead of blindly changing that value as it can
|
||||
# break the overcloud.
|
||||
fail("We couldn't get the live value of the neutron agent, please contact support.")
|
||||
}
|
||||
} else {
|
||||
$host_real = hiera('neutron::host')
|
||||
}
|
||||
|
||||
class { '::neutron' :
|
||||
host => $host_real,
|
||||
rabbit_hosts => $rabbit_endpoints,
|
||||
dhcp_agents_per_network => $dhcp_agents_per_net,
|
||||
}
|
||||
|
|
|
@ -89,8 +89,23 @@ class tripleo::profile::base::nova (
|
|||
$migration_ssh_localaddrs_real = unique($migration_ssh_localaddrs)
|
||||
|
||||
if $step >= 4 or ($step >= 3 and $sync_db) {
|
||||
|
||||
if hiera('stack_action', undef) == 'UPDATE' {
|
||||
if empty($::current_nova_host) {
|
||||
# We fail instead of blindly changing that value as it can
|
||||
# break the overcloud.
|
||||
fail("We couldn't get the live value of the nova agent, please contact support.")
|
||||
} else {
|
||||
$host_real = $::current_nova_host
|
||||
}
|
||||
} else {
|
||||
$host_real = hiera('nova::host')
|
||||
}
|
||||
|
||||
|
||||
$rabbit_endpoints = suffix(any2array(normalize_ip_for_uri($rabbit_hosts)), ":${rabbit_port}")
|
||||
class { '::nova' :
|
||||
host => $host_real,
|
||||
rabbit_hosts => $rabbit_endpoints,
|
||||
}
|
||||
include ::nova::config
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#
|
||||
# Copyright (C) 2017 Red Hat, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'tripleo::profile::base::neutron' do
|
||||
let :params do
|
||||
{ :step => 5}
|
||||
end
|
||||
|
||||
shared_examples_for 'tripleo::profile::base::neutron' do
|
||||
before :each do
|
||||
facts.merge!({ :step => params[:step] })
|
||||
end
|
||||
|
||||
context "during deployment" do
|
||||
let(:facts) { super().merge({:current_neutron_host => ''})}
|
||||
it 'should set neutron::host to fqdn_canonical' do
|
||||
is_expected.to contain_class('neutron').with(:host => 'node.example.com')
|
||||
end
|
||||
end
|
||||
|
||||
context 'during upgrade' do
|
||||
let(:facts) { super().merge({:heat_stack_action => '_update'})}
|
||||
context 'when current host is different from fqdn' do
|
||||
let(:facts) { super().merge({:current_neutron_host => 'node'})}
|
||||
it "should use the current_host" do
|
||||
is_expected.to contain_class('neutron').with(
|
||||
:host => 'node',
|
||||
)
|
||||
end
|
||||
end
|
||||
context 'when current neutron host cannot be found but nova host can' do
|
||||
let(:facts) { super().merge({:current_neutron_host => '',
|
||||
:current_nova_host => 'node'})}
|
||||
it "should use the current_nova_host" do
|
||||
is_expected.to contain_class('neutron').with(
|
||||
:host => 'node',
|
||||
)
|
||||
end
|
||||
end
|
||||
context 'when both nova and neutron current host cannot be found' do
|
||||
let(:facts) { super().merge({:current_neutron_host => '',
|
||||
:current_nova_host => '',
|
||||
})}
|
||||
it "fails" do
|
||||
is_expected.to compile.and_raise_error(/live value of the neutron/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
on_supported_os.each do |os, facts|
|
||||
context "on #{os}" do
|
||||
let(:facts) do
|
||||
facts.merge({
|
||||
:hostname => 'node.example.com',
|
||||
:current_neutron_host => 'node.example.com'
|
||||
})
|
||||
end
|
||||
|
||||
it_behaves_like 'tripleo::profile::base::neutron'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -43,6 +43,7 @@ describe 'tripleo::profile::base::nova' do
|
|||
it {
|
||||
is_expected.to contain_class('tripleo::profile::base::nova')
|
||||
is_expected.to contain_class('nova').with(
|
||||
:host => 'node.example.com',
|
||||
:rabbit_hosts => ['127.0.0.1:5672']
|
||||
|
||||
)
|
||||
|
@ -496,13 +497,35 @@ describe 'tripleo::profile::base::nova' do
|
|||
}
|
||||
end
|
||||
|
||||
context 'during upgrade' do
|
||||
let(:params) { {
|
||||
:step => 4,
|
||||
} }
|
||||
let(:facts) { super().merge({:heat_stack_action => '_update'})}
|
||||
|
||||
context 'when current nova host is different from fqdn' do
|
||||
let(:facts) { super().merge({:current_nova_host => 'node'})}
|
||||
it "should use the current_host" do
|
||||
is_expected.to contain_class('nova').with(
|
||||
:host => 'node',
|
||||
)
|
||||
end
|
||||
end
|
||||
context 'when current nova host cannot be found' do
|
||||
let(:facts) { super().merge({:current_nova_host => ''})}
|
||||
it "fails" do
|
||||
is_expected.to compile.and_raise_error(/live value of the nova/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
on_supported_os.each do |os, facts|
|
||||
context "on #{os}" do
|
||||
let(:facts) do
|
||||
facts.merge({ :hostname => 'node.example.com' })
|
||||
facts.merge({:hostname => 'node.example.com'})
|
||||
end
|
||||
|
||||
it_behaves_like 'tripleo::profile::base::nova'
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
:datadir: './spec/fixtures/hieradata'
|
||||
:hierarchy:
|
||||
- default
|
||||
- 'host_param%{::heat_stack_action}'
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
neutron::host: 'node.example.com'
|
||||
nova::host: 'node.example.com'
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
stack_action: 'UPDATE'
|
||||
neutron::host: 'node.example.com'
|
||||
nova::host: 'node.example.com'
|
Loading…
Reference in New Issue