Add disable_power_off field to the node model

No actual logic behind it and not exposed in the API yet.

Partial-Bug: #2077432
Change-Id: Ibf1f51ab4fc62c081bbaf487aa31018d340e45e8
This commit is contained in:
Dmitry Tantsur 2024-09-23 18:22:08 +02:00
parent e25cff9621
commit b1e38a45c4
No known key found for this signature in database
GPG Key ID: 315B2AF9FD216C60
6 changed files with 63 additions and 20 deletions

View File

@ -781,7 +781,7 @@ RELEASE_MAPPING = {
'objects': { 'objects': {
'Allocation': ['1.1'], 'Allocation': ['1.1'],
'BIOSSetting': ['1.1'], 'BIOSSetting': ['1.1'],
'Node': ['1.40'], 'Node': ['1.41'],
'NodeHistory': ['1.0'], 'NodeHistory': ['1.0'],
'NodeInventory': ['1.0'], 'NodeInventory': ['1.0'],
'Conductor': ['1.4'], 'Conductor': ['1.4'],

View File

@ -0,0 +1,31 @@
# 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.
"""node disable_power_off
Revision ID: 6e9cf6acce0b
Revises: 66bd9c5604d5
Create Date: 2024-09-23 17:54:49.101988
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '6e9cf6acce0b'
down_revision = '66bd9c5604d5'
def upgrade():
op.add_column('nodes', sa.Column('disable_power_off', sa.Boolean(),
nullable=True, server_default=sa.false()))

View File

@ -218,6 +218,8 @@ class NodeBase(Base):
shard = Column(String(255), nullable=True) shard = Column(String(255), nullable=True)
parent_node = Column(String(36), nullable=True) parent_node = Column(String(36), nullable=True)
service_step = Column(db_types.JsonEncodedDict) service_step = Column(db_types.JsonEncodedDict)
disable_power_off = Column(Boolean, nullable=True, default=False,
server_default=false())
class Node(NodeBase): class Node(NodeBase):

View File

@ -82,7 +82,8 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
# Version 1.38: Add parent_node field # Version 1.38: Add parent_node field
# Version 1.39: Add firmware_interface field # Version 1.39: Add firmware_interface field
# Version 1.40: Add service_step field # Version 1.40: Add service_step field
VERSION = '1.40' # Version 1.41: Add disable_power_off field
VERSION = '1.41'
dbapi = db_api.get_instance() dbapi = db_api.get_instance()
@ -182,6 +183,7 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
'secure_boot': object_fields.BooleanField(nullable=True), 'secure_boot': object_fields.BooleanField(nullable=True),
'shard': object_fields.StringField(nullable=True), 'shard': object_fields.StringField(nullable=True),
'parent_node': object_fields.StringField(nullable=True), 'parent_node': object_fields.StringField(nullable=True),
'disable_power_off': objects.fields.BooleanField(nullable=True),
} }
def as_dict(self, secure=False, mask_configdrive=True): def as_dict(self, secure=False, mask_configdrive=True):
@ -695,18 +697,18 @@ class Node(base.IronicObject, object_base.VersionedObjectDictCompat):
self._adjust_field_to_version(name, None, target_version, self._adjust_field_to_version(name, None, target_version,
1, minor, remove_unavailable_fields) 1, minor, remove_unavailable_fields)
# NOTE(dtantsur): the default is False for protected boolean_fields = [('protected', 29, False),
self._adjust_field_to_version('protected', False, target_version, ('retired', 33, False),
1, 29, remove_unavailable_fields) ('disable_power_off', 41, False)]
for name, minor, default in boolean_fields:
self._adjust_field_to_version(name, default, target_version,
1, minor, remove_unavailable_fields)
self._convert_deploy_step_field(target_version, self._convert_deploy_step_field(target_version,
remove_unavailable_fields) remove_unavailable_fields)
self._convert_conductor_group_field(target_version, self._convert_conductor_group_field(target_version,
remove_unavailable_fields) remove_unavailable_fields)
self._adjust_field_to_version('retired', False, target_version,
1, 33, remove_unavailable_fields)
self._convert_network_data_field(target_version, self._convert_network_data_field(target_version,
remove_unavailable_fields) remove_unavailable_fields)
@ -790,6 +792,7 @@ class NodePayload(notification.NotificationPayloadBase):
'created_at': ('node', 'created_at'), 'created_at': ('node', 'created_at'),
'deploy_step': ('node', 'deploy_step'), 'deploy_step': ('node', 'deploy_step'),
'description': ('node', 'description'), 'description': ('node', 'description'),
'disable_power_off': ('node', 'disable_power_off'),
'driver': ('node', 'driver'), 'driver': ('node', 'driver'),
'extra': ('node', 'extra'), 'extra': ('node', 'extra'),
'boot_mode': ('node', 'boot_mode'), 'boot_mode': ('node', 'boot_mode'),
@ -849,7 +852,8 @@ class NodePayload(notification.NotificationPayloadBase):
# Version 1.14: Add retired and retired_reason fields exposed via API. # Version 1.14: Add retired and retired_reason fields exposed via API.
# Version 1.15: Add node lessee field. # Version 1.15: Add node lessee field.
# Version 1.16: Add boot_mode and secure_boot fields. # Version 1.16: Add boot_mode and secure_boot fields.
VERSION = '1.16' # Version 1.17: Add disable_power_off field.
VERSION = '1.17'
fields = { fields = {
'clean_step': object_fields.FlexibleDictField(nullable=True), 'clean_step': object_fields.FlexibleDictField(nullable=True),
'conductor_group': object_fields.StringField(nullable=True), 'conductor_group': object_fields.StringField(nullable=True),
@ -857,6 +861,7 @@ class NodePayload(notification.NotificationPayloadBase):
'created_at': object_fields.DateTimeField(nullable=True), 'created_at': object_fields.DateTimeField(nullable=True),
'deploy_step': object_fields.FlexibleDictField(nullable=True), 'deploy_step': object_fields.FlexibleDictField(nullable=True),
'description': object_fields.StringField(nullable=True), 'description': object_fields.StringField(nullable=True),
'disable_power_off': objects.fields.BooleanField(nullable=True),
'driver': object_fields.StringField(nullable=True), 'driver': object_fields.StringField(nullable=True),
'extra': object_fields.FlexibleDictField(nullable=True), 'extra': object_fields.FlexibleDictField(nullable=True),
'boot_mode': object_fields.StringField(nullable=True), 'boot_mode': object_fields.StringField(nullable=True),
@ -941,7 +946,8 @@ class NodeSetPowerStatePayload(NodePayload):
# Version 1.14: Parent NodePayload version 1.14 # Version 1.14: Parent NodePayload version 1.14
# Version 1.15: Parent NodePayload version 1.15 # Version 1.15: Parent NodePayload version 1.15
# Version 1.16: Parent NodePayload version 1.16 # Version 1.16: Parent NodePayload version 1.16
VERSION = '1.16' # Version 1.17: Parent NodePayload version 1.17
VERSION = '1.17'
fields = { fields = {
# "to_power" indicates the future target_power_state of the node. A # "to_power" indicates the future target_power_state of the node. A
@ -998,7 +1004,8 @@ class NodeCorrectedPowerStatePayload(NodePayload):
# Version 1.14: Parent NodePayload version 1.14 # Version 1.14: Parent NodePayload version 1.14
# Version 1.15: Parent NodePayload version 1.15 # Version 1.15: Parent NodePayload version 1.15
# Version 1.16: Parent NodePayload version 1.16 # Version 1.16: Parent NodePayload version 1.16
VERSION = '1.16' # Version 1.17: Parent NodePayload version 1.17
VERSION = '1.17'
fields = { fields = {
'from_power': object_fields.StringField(nullable=True) 'from_power': object_fields.StringField(nullable=True)
@ -1040,7 +1047,8 @@ class NodeSetProvisionStatePayload(NodePayload):
# Version 1.15: Parent NodePayload version 1.15 # Version 1.15: Parent NodePayload version 1.15
# Version 1.16: add driver_internal_info # Version 1.16: add driver_internal_info
# Version 1.17: Parent NodePayload version 1.16 # Version 1.17: Parent NodePayload version 1.16
VERSION = '1.17' # Version 1.18: Parent NodePayload version 1.17
VERSION = '1.18'
SCHEMA = dict(NodePayload.SCHEMA, SCHEMA = dict(NodePayload.SCHEMA,
**{'instance_info': ('node', 'instance_info'), **{'instance_info': ('node', 'instance_info'),
@ -1090,7 +1098,8 @@ class NodeCRUDPayload(NodePayload):
# Version 1.12: Parent NodePayload version 1.14 # Version 1.12: Parent NodePayload version 1.14
# Version 1.13: Parent NodePayload version 1.15 # Version 1.13: Parent NodePayload version 1.15
# Version 1.14: Parent NodePayload version 1.16 # Version 1.14: Parent NodePayload version 1.16
VERSION = '1.14' # Version 1.15: Parent NodePayload version 1.17
VERSION = '1.15'
SCHEMA = dict(NodePayload.SCHEMA, SCHEMA = dict(NodePayload.SCHEMA,
**{'instance_info': ('node', 'instance_info'), **{'instance_info': ('node', 'instance_info'),

View File

@ -235,6 +235,7 @@ def get_test_node(**kw):
'shard': kw.get('shard', None), 'shard': kw.get('shard', None),
'parent_node': kw.get('parent_node', None), 'parent_node': kw.get('parent_node', None),
'service_step': kw.get('service_step'), 'service_step': kw.get('service_step'),
'disable_power_off': kw.get('disable_power_off', False),
} }
for iface in drivers_base.ALL_INTERFACES: for iface in drivers_base.ALL_INTERFACES:

View File

@ -676,7 +676,7 @@ class TestObject(_LocalTest, _TestObject):
# version bump. It is an MD5 hash of the object fields and remotable methods. # version bump. It is an MD5 hash of the object fields and remotable methods.
# The fingerprint values should only be changed if there is a version bump. # The fingerprint values should only be changed if there is a version bump.
expected_object_fingerprints = { expected_object_fingerprints = {
'Node': '1.40-2182d4660bb5d5e4cc5670c37012ef71', 'Node': '1.41-baff7b2b06243d97448b720030b2e612',
'MyObj': '1.5-9459d30d6954bffc7a9afd347a807ca6', 'MyObj': '1.5-9459d30d6954bffc7a9afd347a807ca6',
'Chassis': '1.3-d656e039fd8ae9f34efc232ab3980905', 'Chassis': '1.3-d656e039fd8ae9f34efc232ab3980905',
'Port': '1.11-97bf15b61224f26c65e90f007d78bfd2', 'Port': '1.11-97bf15b61224f26c65e90f007d78bfd2',
@ -684,21 +684,21 @@ expected_object_fingerprints = {
'Conductor': '1.4-a9703208fdab5fab8f1cec420be1b4a7', 'Conductor': '1.4-a9703208fdab5fab8f1cec420be1b4a7',
'EventType': '1.1-aa2ba1afd38553e3880c267404e8d370', 'EventType': '1.1-aa2ba1afd38553e3880c267404e8d370',
'NotificationPublisher': '1.0-51a09397d6c0687771fb5be9a999605d', 'NotificationPublisher': '1.0-51a09397d6c0687771fb5be9a999605d',
'NodePayload': '1.16-9298b3aba63ab2b9c3359afd90fb9230', 'NodePayload': '1.17-4022bb737b058d426a7ff878b1875e5c',
'NodeSetPowerStateNotification': '1.0-59acc533c11d306f149846f922739c15', 'NodeSetPowerStateNotification': '1.0-59acc533c11d306f149846f922739c15',
'NodeSetPowerStatePayload': '1.16-d3695780185716e75683ebbba4f8a2e6', 'NodeSetPowerStatePayload': '1.17-bde6f731995024e718f42021e50ba7b4',
'NodeCorrectedPowerStateNotification': 'NodeCorrectedPowerStateNotification':
'1.0-59acc533c11d306f149846f922739c15', '1.0-59acc533c11d306f149846f922739c15',
'NodeCorrectedPowerStatePayload': '1.16-fdf636b04ba0827ee0c5ec20730b790d', 'NodeCorrectedPowerStatePayload': '1.17-6e1766fc690e0403bc0a323c8f6f12b7',
'NodeSetProvisionStateNotification': 'NodeSetProvisionStateNotification':
'1.0-59acc533c11d306f149846f922739c15', '1.0-59acc533c11d306f149846f922739c15',
'NodeSetProvisionStatePayload': '1.17-4efa07190b276f52fda09d846b4690a8', 'NodeSetProvisionStatePayload': '1.18-ac98c88d6dc8c6c924a415868f0a36e7',
'VolumeConnector': '1.0-3e0252c0ab6e6b9d158d09238a577d97', 'VolumeConnector': '1.0-3e0252c0ab6e6b9d158d09238a577d97',
'VolumeTarget': '1.0-0b10d663d8dae675900b2c7548f76f5e', 'VolumeTarget': '1.0-0b10d663d8dae675900b2c7548f76f5e',
'ChassisCRUDNotification': '1.0-59acc533c11d306f149846f922739c15', 'ChassisCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'ChassisCRUDPayload': '1.0-dce63895d8186279a7dd577cffccb202', 'ChassisCRUDPayload': '1.0-dce63895d8186279a7dd577cffccb202',
'NodeCRUDNotification': '1.0-59acc533c11d306f149846f922739c15', 'NodeCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'NodeCRUDPayload': '1.14-abe3a744767e5ada9f8370cf0caa1862', 'NodeCRUDPayload': '1.15-9168946f843edd5859464aaa40ad70e0',
'PortCRUDNotification': '1.0-59acc533c11d306f149846f922739c15', 'PortCRUDNotification': '1.0-59acc533c11d306f149846f922739c15',
'PortCRUDPayload': '1.4-9411a1701077ae9dc0aea27d6bf586fc', 'PortCRUDPayload': '1.4-9411a1701077ae9dc0aea27d6bf586fc',
'NodeMaintenanceNotification': '1.0-59acc533c11d306f149846f922739c15', 'NodeMaintenanceNotification': '1.0-59acc533c11d306f149846f922739c15',