755 lines
19 KiB
Python
755 lines
19 KiB
Python
# Copyright 2015 Mirantis, 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.
|
|
|
|
"""Fuel 9.0
|
|
|
|
Revision ID: 11a9adc6d36a
|
|
Revises: 2f879fa32f00
|
|
Create Date: 2015-12-15 17:20:49.519542
|
|
|
|
"""
|
|
|
|
from alembic import op
|
|
import six
|
|
import sqlalchemy as sa
|
|
|
|
from oslo_serialization import jsonutils
|
|
|
|
from nailgun import consts
|
|
from nailgun.db.sqlalchemy.models import fields
|
|
from nailgun.utils.migration import upgrade_enum
|
|
|
|
|
|
revision = '11a9adc6d36a'
|
|
down_revision = '43b2cb64dae6'
|
|
|
|
cluster_statuses_old = (
|
|
'new',
|
|
'deployment',
|
|
'stopped',
|
|
'operational',
|
|
'error',
|
|
'remove',
|
|
'update',
|
|
'update_error'
|
|
)
|
|
cluster_statuses_new = (
|
|
'new',
|
|
'deployment',
|
|
'stopped',
|
|
'operational',
|
|
'error',
|
|
'remove',
|
|
'partially_deployed'
|
|
)
|
|
|
|
|
|
def upgrade():
|
|
add_foreign_key_ondelete()
|
|
upgrade_ip_address()
|
|
update_vips_from_network_roles()
|
|
upgrade_node_roles_metadata()
|
|
merge_node_attributes_with_nodes()
|
|
upgrade_node_attributes()
|
|
upgrade_remove_wizard_metadata_from_releases()
|
|
drop_legacy_patching()
|
|
|
|
|
|
def downgrade():
|
|
restore_legacy_patching()
|
|
downgrade_remove_wizard_metadata_from_releases()
|
|
downgrade_node_attributes()
|
|
downgrade_merge_node_attributes_with_nodes()
|
|
downgrade_node_roles_metadata()
|
|
remove_foreign_key_ondelete()
|
|
downgrade_ip_address()
|
|
|
|
|
|
def remove_foreign_key_ondelete():
|
|
op.drop_constraint(
|
|
'attributes_cluster_id_fkey',
|
|
'attributes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'attributes_cluster_id_fkey',
|
|
'attributes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'cluster_changes_cluster_id_fkey',
|
|
'cluster_changes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'cluster_changes_cluster_id_fkey',
|
|
'cluster_changes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'nodegroups_cluster_id_fkey',
|
|
'nodegroups',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'nodegroups_cluster_id_fkey',
|
|
'nodegroups', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'vmware_attributes_cluster_id_fkey',
|
|
'vmware_attributes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'vmware_attributes_cluster_id_fkey',
|
|
'vmware_attributes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'networking_configs_cluster_id_fkey',
|
|
'networking_configs',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'networking_configs_cluster_id_fkey',
|
|
'networking_configs', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'network_groups_nodegroups_fk',
|
|
'network_groups',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'network_groups_nodegroups_fk',
|
|
'network_groups', 'nodegroups',
|
|
['group_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'neutron_config_id_fkey',
|
|
'neutron_config',
|
|
type_='foreignkey'
|
|
)
|
|
|
|
op.create_foreign_key(
|
|
'neutron_config_id_fkey',
|
|
'neutron_config', 'networking_configs',
|
|
['id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'nodes_nodegroups_fk',
|
|
'nodes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'nodes_nodegroups_fk',
|
|
'nodes', 'nodegroups',
|
|
['group_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'nodes_cluster_id_fkey',
|
|
'nodes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'nodes_cluster_id_fkey',
|
|
'nodes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'cluster_plugin_links_cluster_id_fkey',
|
|
'cluster_plugin_links',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'cluster_plugin_links_cluster_id_fkey',
|
|
'cluster_plugin_links', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'node_nic_interfaces_parent_id_fkey',
|
|
'node_nic_interfaces',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'node_nic_interfaces_parent_id_fkey',
|
|
'node_nic_interfaces', 'node_bond_interfaces',
|
|
['parent_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'openstack_configs_cluster_id_fkey',
|
|
'openstack_configs',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'openstack_configs_cluster_id_fkey',
|
|
'openstack_configs', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'openstack_configs_node_id_fkey',
|
|
'openstack_configs',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'openstack_configs_node_id_fkey',
|
|
'openstack_configs', 'nodes',
|
|
['node_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'plugin_links_plugin_id_fkey',
|
|
'plugin_links',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'plugin_links_plugin_id_fkey',
|
|
'plugin_links', 'plugins',
|
|
['plugin_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'tasks_cluster_id_fkey',
|
|
'tasks',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'tasks_cluster_id_fkey',
|
|
'tasks', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'tasks_parent_id_fkey',
|
|
'tasks',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'tasks_parent_id_fkey',
|
|
'tasks', 'tasks',
|
|
['parent_id'], ['id'],
|
|
)
|
|
|
|
|
|
def add_foreign_key_ondelete():
|
|
op.drop_constraint(
|
|
'attributes_cluster_id_fkey',
|
|
'attributes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'attributes_cluster_id_fkey',
|
|
'attributes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'cluster_changes_cluster_id_fkey',
|
|
'cluster_changes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'cluster_changes_cluster_id_fkey',
|
|
'cluster_changes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'nodegroups_cluster_id_fkey',
|
|
'nodegroups',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'nodegroups_cluster_id_fkey',
|
|
'nodegroups', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'vmware_attributes_cluster_id_fkey',
|
|
'vmware_attributes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'vmware_attributes_cluster_id_fkey',
|
|
'vmware_attributes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'networking_configs_cluster_id_fkey',
|
|
'networking_configs',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'networking_configs_cluster_id_fkey',
|
|
'networking_configs', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'network_groups_nodegroups_fk',
|
|
'network_groups',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'network_groups_nodegroups_fk',
|
|
'network_groups', 'nodegroups',
|
|
['group_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'network_groups_release_fkey',
|
|
'network_groups',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'network_groups_release_fk',
|
|
'network_groups', 'releases',
|
|
['release'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'neutron_config_id_fkey',
|
|
'neutron_config',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'neutron_config_id_fkey',
|
|
'neutron_config', 'networking_configs',
|
|
['id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'nodes_nodegroups_fk',
|
|
'nodes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'nodes_nodegroups_fk',
|
|
'nodes', 'nodegroups',
|
|
['group_id'], ['id'],
|
|
ondelete='SET NULL'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'nodes_cluster_id_fkey',
|
|
'nodes',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'nodes_cluster_id_fkey',
|
|
'nodes', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'cluster_plugin_links_cluster_id_fkey',
|
|
'cluster_plugin_links',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'cluster_plugin_links_cluster_id_fkey',
|
|
'cluster_plugin_links', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'node_nic_interfaces_parent_id_fkey',
|
|
'node_nic_interfaces',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'node_nic_interfaces_parent_id_fkey',
|
|
'node_nic_interfaces', 'node_bond_interfaces',
|
|
['parent_id'], ['id'],
|
|
ondelete='SET NULL'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'openstack_configs_cluster_id_fkey',
|
|
'openstack_configs',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'openstack_configs_cluster_id_fkey',
|
|
'openstack_configs', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'openstack_configs_node_id_fkey',
|
|
'openstack_configs',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'openstack_configs_node_id_fkey',
|
|
'openstack_configs', 'nodes',
|
|
['node_id'], ['id'],
|
|
ondelete='SET NULL'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'plugin_links_plugin_id_fkey',
|
|
'plugin_links',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'plugin_links_plugin_id_fkey',
|
|
'plugin_links', 'plugins',
|
|
['plugin_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'tasks_cluster_id_fkey',
|
|
'tasks',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'tasks_cluster_id_fkey',
|
|
'tasks', 'clusters',
|
|
['cluster_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'tasks_parent_id_fkey',
|
|
'tasks',
|
|
type_='foreignkey'
|
|
)
|
|
op.create_foreign_key(
|
|
'tasks_parent_id_fkey',
|
|
'tasks', 'tasks',
|
|
['parent_id'], ['id'],
|
|
ondelete='CASCADE'
|
|
)
|
|
|
|
|
|
def upgrade_ip_address():
|
|
|
|
op.add_column(
|
|
'ip_addrs',
|
|
sa.Column(
|
|
'is_user_defined',
|
|
sa.Boolean,
|
|
nullable=False,
|
|
default=False,
|
|
server_default="false"
|
|
)
|
|
)
|
|
|
|
op.add_column(
|
|
'ip_addrs',
|
|
sa.Column(
|
|
'vip_namespace',
|
|
sa.String(length=25),
|
|
nullable=True,
|
|
default=None,
|
|
server_default=None
|
|
)
|
|
)
|
|
|
|
op.alter_column(
|
|
'ip_addrs',
|
|
'vip_type',
|
|
new_column_name='vip_name',
|
|
type_=sa.String(length=25)
|
|
)
|
|
|
|
|
|
def update_vips_from_network_roles():
|
|
|
|
def _update_network_roles_from_db_metadata(query):
|
|
connection = op.get_bind()
|
|
_vip_name_to_vip_data = {}
|
|
|
|
select = sa.text(query)
|
|
network_roles_metadata = connection.execute(select)
|
|
for network_roles_json in network_roles_metadata:
|
|
if not network_roles_json or not network_roles_json[0]:
|
|
continue
|
|
network_roles = jsonutils.loads(network_roles_json[0])
|
|
# warning: in current schema it is possible that network
|
|
# role is declared as dict
|
|
if isinstance(network_roles, dict):
|
|
network_roles = [network_roles]
|
|
for network_role in network_roles:
|
|
vips = network_role.get('properties', {}).get('vip', [])
|
|
for vip in vips:
|
|
_vip_name_to_vip_data[vip['name']] = vip
|
|
return _vip_name_to_vip_data
|
|
|
|
roles_vip_name_to_vip_data = {}
|
|
|
|
# get namespaces from plugins
|
|
roles_vip_name_to_vip_data.update(
|
|
_update_network_roles_from_db_metadata(
|
|
"SELECT network_roles_metadata from plugins"
|
|
)
|
|
)
|
|
|
|
# get namespaces from releases
|
|
roles_vip_name_to_vip_data.update(
|
|
_update_network_roles_from_db_metadata(
|
|
"SELECT network_roles_metadata from releases"
|
|
)
|
|
)
|
|
|
|
# perform update
|
|
connection = op.get_bind()
|
|
ip_addrs_select = sa.text(
|
|
"SELECT id, vip_name from ip_addrs"
|
|
)
|
|
ip_addrs = connection.execute(ip_addrs_select)
|
|
|
|
ip_addrs_update = sa.sql.text(
|
|
"UPDATE ip_addrs "
|
|
"SET vip_namespace = :vip_namespace WHERE id = :id"
|
|
)
|
|
|
|
existing_names_to_id = dict(
|
|
(vip_name, vip_id) for (vip_id, vip_name) in ip_addrs
|
|
)
|
|
|
|
for vip_name in existing_names_to_id:
|
|
|
|
namespace = roles_vip_name_to_vip_data\
|
|
.get(vip_name, {}).get('namespace')
|
|
|
|
# update only if namespace arrived
|
|
if namespace:
|
|
connection.execute(
|
|
ip_addrs_update,
|
|
id=existing_names_to_id[vip_name],
|
|
vip_namespace=namespace
|
|
)
|
|
|
|
|
|
def downgrade_ip_address():
|
|
op.alter_column(
|
|
'ip_addrs',
|
|
'vip_name',
|
|
new_column_name='vip_type',
|
|
type_=sa.String(length=25)
|
|
)
|
|
op.drop_column('ip_addrs', 'is_user_defined')
|
|
op.drop_column('ip_addrs', 'vip_namespace')
|
|
|
|
|
|
def upgrade_node_roles_metadata():
|
|
connection = op.get_bind()
|
|
select_query = sa.sql.text(
|
|
"SELECT id, roles_metadata FROM releases "
|
|
"WHERE roles_metadata IS NOT NULL")
|
|
update_query = sa.sql.text(
|
|
"UPDATE releases SET roles_metadata = :roles_metadata WHERE id = :id")
|
|
|
|
for id, roles_metadata in connection.execute(select_query):
|
|
roles_metadata = jsonutils.loads(roles_metadata)
|
|
|
|
role_groups = {
|
|
'controller': 'base',
|
|
'compute': 'compute',
|
|
'virt': 'compute',
|
|
'compute-vmware': 'compute',
|
|
'ironic': 'compute',
|
|
'cinder': 'storage',
|
|
'cinder-block-device': 'storage',
|
|
'cinder-vmware': 'storage',
|
|
'ceph-osd': 'storage'
|
|
}
|
|
for role_name, role_metadata in six.iteritems(roles_metadata):
|
|
role_metadata['group'] = role_groups\
|
|
.get(role_name, consts.NODE_ROLE_GROUPS.other)
|
|
|
|
connection.execute(
|
|
update_query,
|
|
id=id,
|
|
roles_metadata=jsonutils.dumps(roles_metadata),
|
|
)
|
|
|
|
|
|
def downgrade_node_roles_metadata():
|
|
connection = op.get_bind()
|
|
select_query = sa.sql.text(
|
|
"SELECT id, roles_metadata FROM releases "
|
|
"WHERE roles_metadata IS NOT NULL")
|
|
update_query = sa.sql.text(
|
|
"UPDATE releases SET roles_metadata = :roles_metadata WHERE id = :id")
|
|
|
|
for id, roles_metadata in connection.execute(select_query):
|
|
roles_metadata = jsonutils.loads(roles_metadata)
|
|
for role_name, role_metadata in six.iteritems(roles_metadata):
|
|
del role_metadata['group']
|
|
connection.execute(
|
|
update_query,
|
|
id=id,
|
|
roles_metadata=jsonutils.dumps(roles_metadata),
|
|
)
|
|
|
|
|
|
def merge_node_attributes_with_nodes():
|
|
connection = op.get_bind()
|
|
|
|
op.add_column(
|
|
'nodes',
|
|
sa.Column(
|
|
'vms_conf',
|
|
fields.JSON(),
|
|
nullable=False,
|
|
server_default='[]'
|
|
)
|
|
)
|
|
|
|
select_query = sa.sql.text('SELECT node_id, vms_conf FROM node_attributes')
|
|
update_query = sa.sql.text(
|
|
'UPDATE nodes SET vms_conf = :vms_conf WHERE id = :node_id')
|
|
|
|
for node_id, vms_conf in connection.execute(select_query):
|
|
connection.execute(update_query, node_id=node_id, vms_conf=vms_conf)
|
|
|
|
op.drop_table('node_attributes')
|
|
|
|
|
|
def downgrade_merge_node_attributes_with_nodes():
|
|
op.create_table(
|
|
'node_attributes',
|
|
sa.Column('id', sa.Integer(), nullable=False),
|
|
sa.Column('node_id', sa.Integer(), nullable=True),
|
|
sa.Column('interfaces', fields.JSON(), nullable=True),
|
|
sa.Column('vms_conf', fields.JSON(),
|
|
nullable=False, server_default='[]'),
|
|
sa.ForeignKeyConstraint(['node_id'], ['nodes.id'], ),
|
|
sa.PrimaryKeyConstraint('id')
|
|
)
|
|
|
|
op.drop_column('nodes', 'vms_conf')
|
|
|
|
|
|
def upgrade_node_attributes():
|
|
op.add_column(
|
|
'nodes',
|
|
sa.Column(
|
|
'attributes',
|
|
fields.JSON(),
|
|
nullable=False,
|
|
server_default='{}'
|
|
)
|
|
)
|
|
|
|
op.add_column(
|
|
'releases',
|
|
sa.Column(
|
|
'node_attributes',
|
|
fields.JSON(),
|
|
nullable=False,
|
|
server_default='{}'
|
|
)
|
|
)
|
|
|
|
|
|
def downgrade_node_attributes():
|
|
op.drop_column('releases', 'node_attributes')
|
|
op.drop_column('nodes', 'attributes')
|
|
|
|
|
|
def upgrade_remove_wizard_metadata_from_releases():
|
|
op.drop_column('releases', 'wizard_metadata')
|
|
|
|
|
|
def downgrade_remove_wizard_metadata_from_releases():
|
|
op.add_column(
|
|
'releases',
|
|
sa.Column(
|
|
'wizard_metadata',
|
|
fields.JSON(),
|
|
nullable=True
|
|
)
|
|
)
|
|
|
|
|
|
def drop_legacy_patching():
|
|
upgrade_enum(
|
|
"clusters", # table
|
|
"status", # column
|
|
"cluster_status", # ENUM name
|
|
cluster_statuses_old, # old options
|
|
cluster_statuses_new, # new options
|
|
)
|
|
|
|
op.drop_constraint(
|
|
'fk_pending_release_id',
|
|
'clusters',
|
|
type_='foreignkey'
|
|
)
|
|
op.drop_column('clusters', 'pending_release_id')
|
|
op.drop_column('releases', 'can_update_from_versions')
|
|
|
|
|
|
def restore_legacy_patching():
|
|
op.add_column(
|
|
'releases',
|
|
sa.Column(
|
|
'can_update_from_versions',
|
|
fields.JSON(),
|
|
nullable=False,
|
|
server_default='[]'
|
|
))
|
|
op.add_column(
|
|
'clusters',
|
|
sa.Column(
|
|
'pending_release_id',
|
|
sa.Integer(),
|
|
nullable=True
|
|
))
|
|
op.create_foreign_key(
|
|
'fk_pending_release_id',
|
|
'clusters',
|
|
'releases',
|
|
['pending_release_id'],
|
|
['id'])
|
|
|
|
upgrade_enum(
|
|
"clusters", # table
|
|
"status", # column
|
|
"cluster_status", # ENUM name
|
|
cluster_statuses_new, # new options
|
|
cluster_statuses_old, # old options
|
|
)
|