Add Node.maintenance_reason
When a node is maintenanced by Ironic or an operator, an operator should know the reason for that. Add a string column to allow Ironic or operators to enter a reason that the node is in maintenance mode. Implements: blueprint maintenance-reason Change-Id: I7c77c92501e53f81704e9b9e5b52e0e2a410cc91
This commit is contained in:
parent
5a2e9b3559
commit
827db7fe72
@ -49,7 +49,7 @@ class NodePatchType(types.JsonPatchType):
|
||||
return defaults + ['/console_enabled', '/last_error',
|
||||
'/power_state', '/provision_state', '/reservation',
|
||||
'/target_power_state', '/target_provision_state',
|
||||
'/provision_updated_at']
|
||||
'/provision_updated_at', '/maintenance_reason']
|
||||
|
||||
@staticmethod
|
||||
def mandatory_attrs():
|
||||
@ -396,6 +396,9 @@ class Node(base.APIBase):
|
||||
maintenance = types.boolean
|
||||
"Indicates whether the node is in maintenance mode."
|
||||
|
||||
maintenance_reason = wsme.wsattr(wtypes.text, readonly=True)
|
||||
"Indicates reason for putting a node in maintenance mode."
|
||||
|
||||
target_provision_state = wsme.wsattr(wtypes.text, readonly=True)
|
||||
"The user modified desired provision state of the node."
|
||||
|
||||
@ -500,7 +503,8 @@ class Node(base.APIBase):
|
||||
properties={'memory_mb': '1024', 'local_gb': '10',
|
||||
'cpus': '1'}, updated_at=time, created_at=time,
|
||||
provision_updated_at=time, instance_info={},
|
||||
maintenance=False, console_enabled=False)
|
||||
maintenance=False, maintenance_reason=None,
|
||||
console_enabled=False)
|
||||
# NOTE(matty_dubs): The chassis_uuid getter() is based on the
|
||||
# _chassis_uuid variable:
|
||||
sample._chassis_uuid = 'edcad704-b2da-41d5-96d9-afd580ecfa12'
|
||||
|
@ -0,0 +1,36 @@
|
||||
# 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.
|
||||
|
||||
"""Add Node.maintenance_reason
|
||||
|
||||
Revision ID: 242cc6a923b3
|
||||
Revises: 487deb87cc9d
|
||||
Create Date: 2014-10-15 23:00:43.164061
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '242cc6a923b3'
|
||||
down_revision = '487deb87cc9d'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('nodes', sa.Column('maintenance_reason',
|
||||
sa.Text(),
|
||||
nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_column('nodes', 'maintenance_reason')
|
@ -180,6 +180,7 @@ class Node(Base):
|
||||
nullable=True)
|
||||
|
||||
maintenance = Column(Boolean, default=False)
|
||||
maintenance_reason = Column(Text, nullable=True)
|
||||
console_enabled = Column(Boolean, default=False)
|
||||
extra = Column(JSONEncodedDict)
|
||||
|
||||
|
@ -30,7 +30,8 @@ class Node(base.IronicObject):
|
||||
# Version 1.5: Add list()
|
||||
# Version 1.6: Add reserve() and release()
|
||||
# Version 1.7: Add conductor_affinity
|
||||
VERSION = '1.7'
|
||||
# Version 1.8: Add maintenance_reason
|
||||
VERSION = '1.8'
|
||||
|
||||
dbapi = db_api.get_instance()
|
||||
|
||||
@ -65,6 +66,7 @@ class Node(base.IronicObject):
|
||||
'target_provision_state': obj_utils.str_or_none,
|
||||
|
||||
'maintenance': bool,
|
||||
'maintenance_reason': obj_utils.str_or_none,
|
||||
'console_enabled': bool,
|
||||
|
||||
# Any error from the most recent (last) asynchronous transaction
|
||||
|
@ -97,6 +97,7 @@ class TestListNodes(base.FunctionalTest):
|
||||
self.assertNotIn('target_power_state', data['nodes'][0])
|
||||
self.assertNotIn('target_provision_state', data['nodes'][0])
|
||||
self.assertNotIn('provision_updated_at', data['nodes'][0])
|
||||
self.assertNotIn('maintenance_reason', data['nodes'][0])
|
||||
# never expose the chassis_id
|
||||
self.assertNotIn('chassis_id', data['nodes'][0])
|
||||
|
||||
@ -110,6 +111,7 @@ class TestListNodes(base.FunctionalTest):
|
||||
self.assertIn('properties', data)
|
||||
self.assertIn('chassis_uuid', data)
|
||||
self.assertIn('reservation', data)
|
||||
self.assertIn('maintenance_reason', data)
|
||||
# never expose the chassis_id
|
||||
self.assertNotIn('chassis_id', data)
|
||||
|
||||
|
@ -321,6 +321,13 @@ class MigrationCheckersMixin(object):
|
||||
(sqlalchemy.exc.IntegrityError, db_exc.DBDuplicateEntry),
|
||||
nodes.insert().execute, data)
|
||||
|
||||
def _check_242cc6a923b3(self, engine, data):
|
||||
nodes = db_utils.get_table(engine, 'nodes')
|
||||
col_names = [column.name for column in nodes.c]
|
||||
self.assertIn('maintenance_reason', col_names)
|
||||
self.assertIsInstance(nodes.c.maintenance_reason.type,
|
||||
sqlalchemy.types.String)
|
||||
|
||||
def test_upgrade_and_version(self):
|
||||
with patch_with_engine(self.engine):
|
||||
self.migration_api.upgrade('head')
|
||||
|
@ -169,6 +169,7 @@ def get_test_node(**kw):
|
||||
'properties': kw.get('properties', properties),
|
||||
'reservation': kw.get('reservation'),
|
||||
'maintenance': kw.get('maintenance', False),
|
||||
'maintenance_reason': kw.get('maintenance_reason'),
|
||||
'console_enabled': kw.get('console_enabled', False),
|
||||
'extra': kw.get('extra', {}),
|
||||
'updated_at': kw.get('created_at'),
|
||||
|
Loading…
Reference in New Issue
Block a user