nova/nova/virt/zvm/utils.py

127 lines
4.5 KiB
Python

# Copyright 2017,2018 IBM Corp.
#
# 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.
import os
from urllib import parse as urlparse
from oslo_log import log as logging
import six
from zvmconnector import connector
from oslo_utils import fileutils
from nova.api.metadata import base as instance_metadata
from nova import conf
from nova import exception
from nova.virt import configdrive
CONF = conf.CONF
LOG = logging.getLogger(__name__)
class ConnectorClient(object):
"""Request handler to zVM cloud connector"""
def __init__(self, zcc_url, ca_file=None):
_url = urlparse.urlparse(zcc_url)
_ssl_enabled = False
if _url.scheme == 'https':
_ssl_enabled = True
elif ca_file:
LOG.warning("url is %(url)s which is not https "
"but ca_file is configured to %(ca_file)s",
{'url': zcc_url, 'ca_file': ca_file})
if _ssl_enabled and ca_file:
self._conn = connector.ZVMConnector(_url.hostname, _url.port,
ssl_enabled=_ssl_enabled,
verify=ca_file)
else:
self._conn = connector.ZVMConnector(_url.hostname, _url.port,
ssl_enabled=_ssl_enabled,
verify=False)
def call(self, func_name, *args, **kwargs):
results = self._conn.send_request(func_name, *args, **kwargs)
if results['overallRC'] != 0:
LOG.error("zVM Cloud Connector request %(api)s failed with "
"parameters: %(args)s %(kwargs)s . Results: %(results)s",
{'api': func_name, 'args': six.text_type(args),
'kwargs': six.text_type(kwargs),
'results': six.text_type(results)})
raise exception.ZVMConnectorError(results=results)
return results['output']
def _get_instance_path(instance_uuid):
instance_folder = os.path.join(os.path.normpath(CONF.instances_path),
instance_uuid)
fileutils.ensure_tree(instance_folder)
return instance_folder
def _create_config_drive(context, instance_path, instance,
injected_files, network_info, admin_password):
if CONF.config_drive_format != 'iso9660':
raise exception.ConfigDriveUnsupportedFormat(
format=CONF.config_drive_format)
LOG.debug('Using config drive', instance=instance)
extra_md = {}
if admin_password:
extra_md['admin_pass'] = admin_password
inst_md = instance_metadata.InstanceMetadata(instance,
content=injected_files,
extra_md=extra_md,
network_info=network_info)
configdrive_iso = os.path.join(instance_path, 'cfgdrive.iso')
LOG.debug('Creating config drive at %s', configdrive_iso,
instance=instance)
with configdrive.ConfigDriveBuilder(instance_md=inst_md) as cdb:
cdb.make_drive(configdrive_iso)
return configdrive_iso
# Prepare and create configdrive for instance
def generate_configdrive(context, instance, injected_files,
network_info, admin_password):
# Create network configuration files
LOG.debug('Creating config drive configuration files '
'for instance: %s', instance.name, instance=instance)
instance_path = _get_instance_path(instance.uuid)
transportfiles = None
if configdrive.required_by(instance):
transportfiles = _create_config_drive(context, instance_path,
instance,
injected_files,
network_info,
admin_password)
return transportfiles
def clean_up_file(filepath):
if os.path.exists(filepath):
os.remove(filepath)