Add upgrade status check for incomplete consumers
Since the create_incomplete_consumers online data migration was copied from nova to placement, and will eventually be removed from nova (and the nova online data migration won't help once the placement data is copied over to extracted placement on upgrade anyway), this adds an upgrade check to make sure operators completed that online data migration. Normally we wouldn't add upgrade checks for online data migrations which should get automatically run by deployment tools, but since extracted placement is very new, it's nice to provide tooling to let operators know they have not only properly migrated their data to extracted placement but whether or not their upgrade homework is done. Change-Id: I7f3ba20153a4c1dc8f5b209024edb882fcb726ef
This commit is contained in:
parent
510b48482b
commit
0f97cebedd
@ -88,4 +88,5 @@ Upgrade
|
||||
|
||||
**1.0.0 (Stein)**
|
||||
|
||||
* Placeholder to be filled in with checks as they are added in Stein.
|
||||
* A check was added for incomplete consumers which can be remedied by running
|
||||
the ``placement-manage db online_data_migrations`` command.
|
||||
|
@ -15,6 +15,9 @@ import sys
|
||||
from oslo_config import cfg
|
||||
from oslo_upgradecheck import upgradecheck
|
||||
|
||||
from placement import context
|
||||
from placement.db.sqlalchemy import models
|
||||
from placement import db_api
|
||||
from placement.i18n import _
|
||||
|
||||
|
||||
@ -24,10 +27,47 @@ class Checks(upgradecheck.UpgradeCommands):
|
||||
Various upgrade checks should be added as separate methods in this class
|
||||
and added to _upgrade_checks tuple.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.ctxt = context.RequestContext(config=cfg.CONF)
|
||||
|
||||
def _check_placeholder(self):
|
||||
# This is just a placeholder for upgrade checks, it should be
|
||||
# removed when the actual checks are added
|
||||
@db_api.placement_context_manager.reader
|
||||
def _count_missing_consumers(self, ctxt):
|
||||
# Count the total number of consumers.
|
||||
num_consumers = ctxt.session.query(models.Consumer).count()
|
||||
# Count the total number of unique consumers in the allocations table.
|
||||
num_alloc_consumers = ctxt.session.query(models.Allocation).group_by(
|
||||
models.Allocation.consumer_id).count()
|
||||
return num_alloc_consumers - num_consumers
|
||||
|
||||
def _check_incomplete_consumers(self):
|
||||
"""Allocations created with microversion<1.8 prior to Rocky will not
|
||||
have an associated consumers table record. Starting in Rocky with
|
||||
the 1.28 microversion, consumer generations were added to avoid
|
||||
multiple processes overwriting allocations. Older allocations with
|
||||
incomplete consumer records will be online migrated when accessed
|
||||
via the REST API or when the
|
||||
"placement-manage db online_data_migrations" command is run during
|
||||
an upgrade. This status check emits a warning if there are incomplete
|
||||
consumers to remind operators to perform the data migration.
|
||||
|
||||
Note that normally we would not add an upgrade status check to simply
|
||||
mirror an online data migration since online data migrations should
|
||||
be part of deploying/upgrading placement automation. However, with
|
||||
placement being freshly extracted from nova, this check serves as a
|
||||
friendly reminder and because the data migration will eventually be
|
||||
removed from nova along with the rest of the placement code.
|
||||
"""
|
||||
missing_consumer_count = self._count_missing_consumers(self.ctxt)
|
||||
if missing_consumer_count:
|
||||
# We found missing consumers for existing allocations so return
|
||||
# a warning and tell the user to run the online data migrations.
|
||||
return upgradecheck.Result(
|
||||
upgradecheck.Code.WARNING,
|
||||
details=_('There are %s incomplete consumers table records '
|
||||
'for existing allocations. Run the '
|
||||
'"placement-manage db online_data_migrations" '
|
||||
'command.') % missing_consumer_count)
|
||||
# No missing consumers (or no allocations [fresh install?]) so it's OK.
|
||||
return upgradecheck.Result(upgradecheck.Code.SUCCESS)
|
||||
|
||||
# The format of the check functions is to return an
|
||||
@ -38,11 +78,7 @@ class Checks(upgradecheck.UpgradeCommands):
|
||||
# in the returned Result's "details" attribute. The
|
||||
# summary will be rolled up at the end of the check() method.
|
||||
_upgrade_checks = (
|
||||
# TODO(mriedem) In the future there should be some real checks added
|
||||
# here, for example, making sure all resource providers have a
|
||||
# root_provider_id set before the nested RPs compatibility code is
|
||||
# removed. See bug 1799892 for details.
|
||||
(_('Placeholder'), _check_placeholder),
|
||||
(_('Incomplete Consumers'), _check_incomplete_consumers),
|
||||
)
|
||||
|
||||
|
||||
|
0
placement/tests/functional/cmd/__init__.py
Normal file
0
placement/tests/functional/cmd/__init__.py
Normal file
44
placement/tests/functional/cmd/test_status.py
Normal file
44
placement/tests/functional/cmd/test_status.py
Normal file
@ -0,0 +1,44 @@
|
||||
# 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.
|
||||
|
||||
from oslo_upgradecheck import upgradecheck
|
||||
|
||||
from placement.cmd import status
|
||||
from placement.objects import consumer
|
||||
from placement.tests.functional import base
|
||||
from placement.tests.functional.db import test_consumer
|
||||
|
||||
|
||||
class UpgradeCheckIncompleteConsumersTestCase(
|
||||
base.TestCase, test_consumer.CreateIncompleteAllocationsMixin):
|
||||
"""Tests the "Incomplete Consumers" check for the
|
||||
"placement-status upgrade check" command.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(UpgradeCheckIncompleteConsumersTestCase, self).setUp()
|
||||
self.checks = status.Checks()
|
||||
|
||||
def test_check_incomplete_consumers(self):
|
||||
# Create some allocations with 3 missing consumers.
|
||||
self._create_incomplete_allocations(
|
||||
self.context, num_of_consumer_allocs=2)
|
||||
result = self.checks._check_incomplete_consumers()
|
||||
# Since there are incomplete consumers, there should be a warning.
|
||||
self.assertEqual(upgradecheck.Code.WARNING, result.code)
|
||||
# Check the details for the consumer count.
|
||||
self.assertIn('There are 3 incomplete consumers table records for '
|
||||
'existing allocations', result.details)
|
||||
# Run the online data migration (as recommended from the check output).
|
||||
consumer.create_incomplete_consumers(self.context, batch_size=50)
|
||||
# Run the check again and it should be successful.
|
||||
result = self.checks._check_incomplete_consumers()
|
||||
self.assertEqual(upgradecheck.Code.SUCCESS, result.code)
|
@ -93,14 +93,9 @@ def _get_allocs_with_no_consumer_relationship(ctx):
|
||||
return ctx.session.execute(sel).fetchall()
|
||||
|
||||
|
||||
# NOTE(jaypipes): The tb.PlacementDbBaseTestCase creates a project and user
|
||||
# which is why we don't base off that. We want a completely bare DB for this
|
||||
# test.
|
||||
class CreateIncompleteConsumersTestCase(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(CreateIncompleteConsumersTestCase, self).setUp()
|
||||
self.ctx = self.context
|
||||
class CreateIncompleteAllocationsMixin(object):
|
||||
"""Mixin for test setup to create some allocations with missing consumers
|
||||
"""
|
||||
|
||||
@db_api.placement_context_manager.writer
|
||||
def _create_incomplete_allocations(self, ctx, num_of_consumer_allocs=1):
|
||||
@ -133,6 +128,17 @@ class CreateIncompleteConsumersTestCase(base.TestCase):
|
||||
res = ctx.session.execute(sel).fetchall()
|
||||
self.assertEqual(0, len(res))
|
||||
|
||||
|
||||
# NOTE(jaypipes): The tb.PlacementDbBaseTestCase creates a project and user
|
||||
# which is why we don't base off that. We want a completely bare DB for this
|
||||
# test.
|
||||
class CreateIncompleteConsumersTestCase(
|
||||
base.TestCase, CreateIncompleteAllocationsMixin):
|
||||
|
||||
def setUp(self):
|
||||
super(CreateIncompleteConsumersTestCase, self).setUp()
|
||||
self.ctx = self.context
|
||||
|
||||
@db_api.placement_context_manager.reader
|
||||
def _check_incomplete_consumers(self, ctx):
|
||||
config = ctx.config
|
||||
|
@ -1,32 +0,0 @@
|
||||
# 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.
|
||||
|
||||
from oslo_upgradecheck.upgradecheck import Code
|
||||
import testtools
|
||||
|
||||
from placement.cmd import status
|
||||
|
||||
|
||||
class TestUpgradeChecks(testtools.TestCase):
|
||||
"""Basic tests for the upgrade check framework.
|
||||
|
||||
The heavy lifting is done in the oslo.upgradecheck library and the
|
||||
tests here do not attempt to test the internals of the library code.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestUpgradeChecks, self).setUp()
|
||||
self.cmd = status.Checks()
|
||||
|
||||
def test_check_placeholder(self):
|
||||
check_result = self.cmd._check_placeholder()
|
||||
self.assertEqual(
|
||||
Code.SUCCESS, check_result.code)
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
An upgrade check was added to the ``placement-status upgrade check``
|
||||
command for incomplete consumers which can be remedied by running the
|
||||
``placement-manage db online_data_migrations`` command.
|
Loading…
Reference in New Issue
Block a user