Remove scripts for migrating nova baremetal
In juno, ironic provided support for migrating from nova's "baremetal" driver to its "ironic" driver. These scripts were used for that. The baremetal driver was removed from nova in kilo. Ironic doesn't support migrating from pre-kilo nova's baremetal driver to post-juno nova's ironic driver. Hence, deleting these migration scripts. Closes-Bug: #1446330 Change-Id: Ic4990caa83a2eca3ee9fbd105bfe0a12bdaa7efe
This commit is contained in:
parent
d499734509
commit
76ab94fcbd
@ -1,318 +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 __future__ import print_function
|
||||
import argparse
|
||||
import ConfigParser
|
||||
import os
|
||||
import sys
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
from ironic.common import states as ironic_states
|
||||
from ironic.db.sqlalchemy import models as ironic_models
|
||||
from ironic.migrate_nova import nova_baremetal_states as nova_states
|
||||
from ironic.migrate_nova import nova_models
|
||||
|
||||
|
||||
DESCRIPTION = """
|
||||
This is an administrative utility to be used for migrating a nova-baremetal
|
||||
node inventory to Ironic. It will migrate nova-baremetal node and interface
|
||||
information and associated driver configuration from the Nova database to the
|
||||
Ironic database. It only supports migrating from the IPMI and
|
||||
VirtualPowerManager power drivers.
|
||||
"""
|
||||
|
||||
IRONIC_ENGINE = None
|
||||
NOVA_BM_ENGINE = None
|
||||
|
||||
|
||||
# Relevant nova-baremetal config with their associated defaults as of Juno.
|
||||
NOVA_BM_CONFIG_KEYS = {
|
||||
# nova.virt.baremetal.driver
|
||||
'driver': 'nova.virt.baremetal.pxe.PXE',
|
||||
'power_manager': 'nova.virt.baremetal.ipmi.IPMI',
|
||||
|
||||
# nova.virt.baremetal.virtual_power_driver
|
||||
'virtual_power_ssh_host': '',
|
||||
'virtual_power_ssh_port': 22,
|
||||
'virtual_power_type': 'virsh',
|
||||
'virtual_power_host_user': '',
|
||||
'virtual_power_host_pass': '',
|
||||
'virtual_power_host_key': '',
|
||||
}
|
||||
|
||||
|
||||
def get_nova_nodes():
|
||||
Session = sessionmaker(bind=NOVA_BM_ENGINE)
|
||||
session = Session()
|
||||
query = session.query(nova_models.BareMetalNode)
|
||||
|
||||
try:
|
||||
nodes = query.all()
|
||||
except sa.exc.OperationalError as err:
|
||||
print("Could not get nodes from Nova:\n%s" % err, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
session.close()
|
||||
|
||||
return nodes
|
||||
|
||||
|
||||
def get_nova_ports():
|
||||
Session = sessionmaker(bind=NOVA_BM_ENGINE)
|
||||
session = Session()
|
||||
|
||||
query = session.query(nova_models.BareMetalInterface)
|
||||
|
||||
try:
|
||||
ports = query.all()
|
||||
except sa.exc.OperationalError as err:
|
||||
print("Could not get ports from Nova:\n%s" % err, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
session.close()
|
||||
|
||||
return ports
|
||||
|
||||
|
||||
def convert_nova_nodes(nodes, cpu_arch, nova_conf):
|
||||
ironic_nodes = []
|
||||
|
||||
for n_node in nodes:
|
||||
# Create an empty Ironic Node
|
||||
i_node = ironic_models.Node()
|
||||
|
||||
# Populate basic properties
|
||||
i_node.id = n_node.id
|
||||
i_node.uuid = n_node.uuid
|
||||
i_node.chassis_id = None
|
||||
i_node.last_error = None
|
||||
i_node.instance_uuid = n_node.instance_uuid
|
||||
i_node.reservation = None
|
||||
i_node.maintenance = False
|
||||
i_node.updated_at = n_node.updated_at
|
||||
i_node.created_at = n_node.created_at
|
||||
|
||||
# Populate states
|
||||
if n_node.task_state == nova_states.ACTIVE:
|
||||
i_node.power_state = ironic_states.POWER_ON
|
||||
else:
|
||||
i_node.power_state = ironic_states.POWER_OFF
|
||||
|
||||
i_node.target_power_state = None
|
||||
|
||||
if i_node.instance_uuid:
|
||||
prov_state = ironic_states.ACTIVE
|
||||
else:
|
||||
prov_state = ironic_states.NOSTATE
|
||||
|
||||
i_node.provision_state = prov_state
|
||||
i_node.target_provision_state = None
|
||||
|
||||
# Populate extra properties
|
||||
i_node.extra = {}
|
||||
|
||||
# Populate driver_info
|
||||
i_node.driver_info = {}
|
||||
|
||||
power_manager = nova_conf['power_manager']
|
||||
if power_manager.endswith('IPMI'):
|
||||
i_node.driver = 'pxe_ipmitool'
|
||||
if n_node.pm_address:
|
||||
i_node.driver_info['ipmi_address'] = n_node.pm_address
|
||||
if n_node.pm_user:
|
||||
i_node.driver_info['ipmi_username'] = n_node.pm_user
|
||||
if n_node.pm_password:
|
||||
i_node.driver_info['ipmi_password'] = n_node.pm_password
|
||||
elif power_manager.endswith('VirtualPowerManager'):
|
||||
i_node.driver = 'pxe_ssh'
|
||||
i_node.driver_info = {
|
||||
'ssh_virt_type': nova_conf['virtual_power_type'],
|
||||
'ssh_address': nova_conf['virtual_power_ssh_host'],
|
||||
'ssh_username': nova_conf['virtual_power_host_user'],
|
||||
}
|
||||
|
||||
ssh_port = nova_conf.get('ssh_port')
|
||||
if ssh_port:
|
||||
ssh_port = nova_conf['virtual_power_ssh_port']
|
||||
|
||||
ssh_key = nova_conf.get('virtual_power_host_key')
|
||||
if ssh_key:
|
||||
i_node.driver_info['ssh_key_filename'] = ssh_key
|
||||
|
||||
ssh_pass = nova_conf.get('virtual_power_host_pass')
|
||||
if ssh_pass:
|
||||
i_node.driver_info['ssh_password'] = ssh_pass
|
||||
else:
|
||||
print("This does not support migration from power driver: "
|
||||
"%s\n" % nova_conf['driver'], file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
# Populate instance_info
|
||||
i_node.instance_info = {}
|
||||
|
||||
if n_node.root_mb:
|
||||
i_node.instance_info['root_mb'] = n_node.root_mb
|
||||
if n_node.swap_mb:
|
||||
i_node.instance_info['swap_mb'] = n_node.swap_mb
|
||||
if n_node.ephemeral_mb:
|
||||
i_node.instance_info['ephemeral_mb'] = n_node.ephemeral_mb
|
||||
|
||||
i_node.properties = {'cpu_arch': cpu_arch,
|
||||
'cpus': n_node.cpus,
|
||||
'local_gb': n_node.local_gb,
|
||||
'memory_mb': n_node.memory_mb}
|
||||
|
||||
ironic_nodes.append(i_node)
|
||||
|
||||
return ironic_nodes
|
||||
|
||||
|
||||
def convert_nova_ports(ports):
|
||||
ironic_ports = []
|
||||
|
||||
for n_port in ports:
|
||||
i_port = ironic_models.Port()
|
||||
|
||||
i_port.id = n_port.id
|
||||
i_port.uuid = uuidutils.generate_uuid()
|
||||
i_port.address = n_port.address
|
||||
i_port.node_id = n_port.bm_node_id
|
||||
|
||||
i_port.extra = {}
|
||||
|
||||
if n_port.vif_uuid:
|
||||
i_port.extra['vif_uuid'] = n_port.vif_uuid
|
||||
|
||||
ironic_ports.append(i_port)
|
||||
|
||||
return ironic_ports
|
||||
|
||||
|
||||
def save_ironic_objects(objects):
|
||||
Session = sessionmaker(bind=IRONIC_ENGINE)
|
||||
session = Session()
|
||||
|
||||
try:
|
||||
session.add_all(objects)
|
||||
session.commit()
|
||||
except sa.exc.OperationalError as err:
|
||||
print("Could not send data to Ironic:\n%s" % err, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
session.close()
|
||||
|
||||
|
||||
def parse_nova_config(config_file):
|
||||
"""Parse nova.conf and return known defaults if setting is not present.
|
||||
|
||||
This avoids having to import nova code from this script and risk conflicts
|
||||
with Ironic's tree around oslo_config resources.
|
||||
"""
|
||||
if not os.path.isfile(config_file):
|
||||
print("nova.conf not found at %s. Please specify the location via "
|
||||
"the --nova-config option." % config_file, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
nova_conf = ConfigParser.SafeConfigParser()
|
||||
nova_conf.read(config_file)
|
||||
|
||||
conf = {}
|
||||
for setting, default in NOVA_BM_CONFIG_KEYS.items():
|
||||
try:
|
||||
conf[setting] = nova_conf.get('baremetal', setting)
|
||||
except ConfigParser.NoOptionError:
|
||||
conf[setting] = default
|
||||
return conf
|
||||
|
||||
|
||||
def validate_config(config):
|
||||
"""Early validation of required configuration prior to touching the db."""
|
||||
if config['power_manager'].endswith('VirtualPowerManager'):
|
||||
# confirm nova.conf contains all required ssh info, as per
|
||||
# ironic.drivers.ssh.REQUIRED_PROPERTIES.
|
||||
req = ['virtual_power_host_user', 'virtual_power_type',
|
||||
'virtual_power_ssh_host']
|
||||
missing = []
|
||||
for r in req:
|
||||
if not config.get(r):
|
||||
missing.append(r)
|
||||
if missing:
|
||||
print('nova.conf is missing required settings in the '
|
||||
'[baremetal] section to migrate VirtualPowerManager: %s' %
|
||||
' '.join(missing), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description=DESCRIPTION)
|
||||
parser.add_argument('--nova-bm-db', '-b', type=str,
|
||||
required=True, dest='nova_bm_conn_string',
|
||||
help='Connection string to Nova baremetal database.')
|
||||
parser.add_argument('--ironic-db', '-i', type=str,
|
||||
required=True, dest='ironic_conn_string',
|
||||
help='Connection string to Ironic database.')
|
||||
parser.add_argument('--node-arch', '-a', type=str,
|
||||
required=True, dest='cpu_arch',
|
||||
help='CPU architecture of the nodes.')
|
||||
parser.add_argument('--nova-config', '-c', type=str,
|
||||
required=False, dest='nova_config',
|
||||
default='/etc/nova/nova.conf',
|
||||
help='Path to nova.conf. (default: '
|
||||
'/etc/nova/nova.conf)')
|
||||
return parser.parse_args(sys.argv[1:])
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
global IRONIC_ENGINE
|
||||
global NOVA_BM_ENGINE
|
||||
|
||||
IRONIC_ENGINE = sa.create_engine(args.ironic_conn_string)
|
||||
NOVA_BM_ENGINE = sa.create_engine(args.nova_bm_conn_string)
|
||||
|
||||
# Load and validate nova.conf
|
||||
nova_conf = parse_nova_config(args.nova_config)
|
||||
validate_config(nova_conf)
|
||||
|
||||
# Process nodes
|
||||
print("Getting data for baremetal nodes from Nova...")
|
||||
nova_nodes = get_nova_nodes()
|
||||
print("Got %d nodes from Nova..." % len(nova_nodes))
|
||||
|
||||
print("Converting information for Nova nodes to Ironic...")
|
||||
ironic_nodes = convert_nova_nodes(nova_nodes, args.cpu_arch,
|
||||
nova_conf)
|
||||
|
||||
print("Saving nodes to Ironic...")
|
||||
save_ironic_objects(ironic_nodes)
|
||||
|
||||
# Process ports
|
||||
print("Getting baremetal ports from Nova...")
|
||||
nova_ports = get_nova_ports()
|
||||
print("Got %d ports from Nova." % len(nova_ports))
|
||||
|
||||
print("Converting Nova ports...")
|
||||
ironic_ports = convert_nova_ports(nova_ports)
|
||||
print("Saving ports to Ironic...")
|
||||
save_ironic_objects(ironic_ports)
|
||||
|
||||
# Printing summary
|
||||
print("All done!")
|
||||
print("%d nodes and %d ports have been migrated from "
|
||||
"Nova to Ironic." % (len(nova_nodes), len(nova_ports)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,38 +0,0 @@
|
||||
# Copyright (c) 2012 NTT DOCOMO, INC.
|
||||
# Copyright 2010 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# NOTE(adam_g): This code has been copied directly from Nova (J2) to facilitate
|
||||
# Nova baremetal data migration tools. The original may be found in the Nova
|
||||
# tree (nova.virt.baremetal.baremetal_states).
|
||||
|
||||
"""
|
||||
Possible baremetal node states for instances.
|
||||
|
||||
Compute instance baremetal states represent the state of an instance as it
|
||||
pertains to a user or administrator. When combined with task states
|
||||
(task_states.py), a better picture can be formed regarding the instance's
|
||||
health.
|
||||
|
||||
"""
|
||||
|
||||
ACTIVE = 'active'
|
||||
BUILDING = 'building'
|
||||
DEPLOYING = 'deploying'
|
||||
DEPLOYFAIL = 'deploy failed'
|
||||
DEPLOYDONE = 'deploy complete'
|
||||
DELETED = 'deleted'
|
||||
ERROR = 'error'
|
||||
PREPARED = 'prepared'
|
@ -1,71 +0,0 @@
|
||||
# Copyright (c) 2012 NTT DOCOMO, INC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# NOTE(adam_g): This code has been copied directly from Nova (J2) to facilitate
|
||||
# Nova baremetal data migration tools. The original may be found in the Nova
|
||||
# tree (nova.virt.baremetal.db.sqlalchemy.models).
|
||||
|
||||
"""
|
||||
SQLAlchemy models for baremetal data.
|
||||
"""
|
||||
|
||||
from sqlalchemy import Column, Boolean, Integer, String
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import ForeignKey, Text
|
||||
|
||||
from ironic.db.sqlalchemy import models
|
||||
|
||||
|
||||
BASE = declarative_base()
|
||||
|
||||
|
||||
class BareMetalNode(BASE, models.Base):
|
||||
"""Represents a bare metal node."""
|
||||
|
||||
__tablename__ = 'bm_nodes'
|
||||
id = Column(Integer, primary_key=True)
|
||||
deleted = Column(Boolean, default=False)
|
||||
uuid = Column(String(36))
|
||||
service_host = Column(String(255))
|
||||
instance_uuid = Column(String(36))
|
||||
instance_name = Column(String(255))
|
||||
cpus = Column(Integer)
|
||||
memory_mb = Column(Integer)
|
||||
local_gb = Column(Integer)
|
||||
preserve_ephemeral = Column(Boolean)
|
||||
pm_address = Column(Text)
|
||||
pm_user = Column(Text)
|
||||
pm_password = Column(Text)
|
||||
task_state = Column(String(255))
|
||||
terminal_port = Column(Integer)
|
||||
image_path = Column(String(255))
|
||||
pxe_config_path = Column(String(255))
|
||||
deploy_key = Column(String(255))
|
||||
# root_mb, swap_mb and ephemeral_mb are cached flavor values for the
|
||||
# current deployment not attributes of the node.
|
||||
root_mb = Column(Integer)
|
||||
swap_mb = Column(Integer)
|
||||
ephemeral_mb = Column(Integer)
|
||||
|
||||
|
||||
class BareMetalInterface(BASE, models.Base):
|
||||
__tablename__ = 'bm_interfaces'
|
||||
id = Column(Integer, primary_key=True)
|
||||
deleted = Column(Boolean, default=False)
|
||||
bm_node_id = Column(Integer, ForeignKey('bm_nodes.id'))
|
||||
address = Column(String(255), unique=True)
|
||||
datapath_id = Column(String(255))
|
||||
port_no = Column(Integer)
|
||||
vif_uuid = Column(String(36), unique=True)
|
@ -27,7 +27,6 @@ console_scripts =
|
||||
ironic-dbsync = ironic.cmd.dbsync:main
|
||||
ironic-conductor = ironic.cmd.conductor:main
|
||||
ironic-rootwrap = oslo_rootwrap.cmd:main
|
||||
ironic-nova-bm-migrate = ironic.migrate_nova.migrate_db:main
|
||||
|
||||
ironic.dhcp =
|
||||
neutron = ironic.dhcp.neutron:NeutronDHCPApi
|
||||
|
Loading…
Reference in New Issue
Block a user