[Ironic] Ironic deploy support for Fuel Agent

This patch adds support for Ironic Fuel Agent deploy
driver.

Co-Authored-By: Yuriy Zveryanskyy <yzveryanskyy@mirantis.com>
Implements blueprint: baremetal-deploy-ironic

Change-Id: Ia64099b0f99ca1844421e569fad2415c1214713f
This commit is contained in:
Vladyslav Drok 2015-07-14 19:37:17 +03:00 committed by vsaienko
parent cf699820fb
commit bb7b13b6c0
4 changed files with 142 additions and 70 deletions

View File

@ -7,6 +7,10 @@
# Data driver (string value)
#data_driver=nailgun
# Directory where the image is supposed to be built (string
# value)
#image_build_dir=/tmp
# Path to directory with cloud init templates (string value)
#nc_template_path=/usr/share/fuel-agent/cloud-init-templates
@ -29,12 +33,44 @@
# value)
#udev_rename_substr=.renamedrule
# Directory where we build images (string value)
#image_build_dir=/tmp
# Correct empty rule for udev daemon (string value)
#udev_empty_rule=empty_rule
# Directory where we build images (string value)
# Suffix which is used while creating temporary files (string
# value)
#image_build_suffix=.fuel-agent-image
# Timeout in secs for GRUB (integer value)
#grub_timeout=5
# Maximum allowed loop devices count to use (integer value)
#max_loop_devices_count=255
# Size of sparse file in MiBs (integer value)
#sparse_file_size=8192
# System-wide major number for loop device (integer value)
#loop_device_major_number=7
# Maximum allowed debootstrap/apt-get attempts to execute
# (integer value)
#fetch_packages_attempts=10
# File where to store apt setting for unsigned packages
# (string value)
#allow_unsigned_file=allow_unsigned_packages
# File where to store apt setting for forcing IPv4 usage
# (string value)
#force_ipv4_file=force_ipv4
# Create configdrive file, use pre-builded if set to False
# (boolean value)
#prepare_configdrive=true
# Add udev rules for NIC remapping (boolean value)
#fix_udev_net_rules=true
#
# Options defined in fuel_agent.cmd.agent
@ -120,7 +156,6 @@ logging_debug_format_suffix=
# Deprecated group/name - [DEFAULT]/logfile
log_file=/var/log/fuel-agent.log
# (Optional) The base directory used for relative --log-file
# paths. (string value)
# Deprecated group/name - [DEFAULT]/logdir
@ -150,20 +185,6 @@ log_file=/var/log/fuel-agent.log
#data_chunk_size=1048576
#
# Options defined in fuel_agent.utils.build
#
# Maximum allowed loop devices count to use (integer value)
#max_loop_count=255
# Size of sparse file in MiBs (integer value)
#sparse_file_size=2048
# System-wide major number for loop device (integer value)
#loop_dev_major=7
#
# Options defined in fuel_agent.utils.utils
#
@ -182,3 +203,9 @@ log_file=/var/log/fuel-agent.log
# Block size of data to read for calculating checksum (integer
# value)
#read_chunk_size=1048576
# Delay in seconds before the next exectuion will retry
# (floating point value)
#execute_retry_delay=2.0

View File

@ -16,6 +16,7 @@ import itertools
import math
import os
from oslo_config import cfg
import six
from six.moves.urllib.parse import urljoin
from six.moves.urllib.parse import urlparse
@ -33,6 +34,10 @@ from fuel_agent.utils import utils
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
CONF.import_opt('prepare_configdrive', 'fuel_agent.manager')
CONF.import_opt('config_drive_path', 'fuel_agent.manager')
def match_device(hu_disk, ks_disk):
"""Check if hu_disk and ks_disk are the same device
@ -422,7 +427,9 @@ class Nailgun(BaseDataDriver):
self._boot_done = True
# this partition will be used to put there configdrive image
if partition_scheme.configdrive_device() is None:
if (partition_scheme.configdrive_device() is None and
CONF.prepare_configdrive or
os.path.isfile(CONF.config_drive_path)):
LOG.debug('Adding configdrive partition on disk %s: size=20' %
disk['name'])
parted.add_partition(size=20, configdrive=True)
@ -593,6 +600,22 @@ class Nailgun(BaseDataDriver):
return image_scheme
class Ironic(Nailgun):
def __init__(self, data):
super(Ironic, self).__init__(data)
def parse_configdrive_scheme(self):
pass
def parse_partition_scheme(self):
# FIXME(yuriyz): Using of internal attributes of base class is very
# fragile. This code acts only as temporary solution. Ironic should
# use own driver, based on simple driver.
self._boot_partition_done = True
self._boot_done = True
return super(Ironic, self).parse_partition_scheme()
class NailgunBuildImage(BaseDataDriver):
# TODO(kozhukalov):

View File

@ -117,6 +117,16 @@ opts = [
default='force_ipv4',
help='File where to store apt setting for forcing IPv4 usage'
),
cfg.BoolOpt(
'prepare_configdrive',
default=True,
help='Create configdrive file, use pre-builded if set to False'
),
cfg.BoolOpt(
'fix_udev_net_rules',
default=True,
help='Add udev rules for NIC remapping'
),
]
cli_opts = [
@ -251,40 +261,46 @@ class Manager(object):
def do_configdrive(self):
LOG.debug('--- Creating configdrive (do_configdrive) ---')
cc_output_path = os.path.join(CONF.tmp_path, 'cloud_config.txt')
bh_output_path = os.path.join(CONF.tmp_path, 'boothook.txt')
# NOTE:file should be strictly named as 'user-data'
# the same is for meta-data as well
ud_output_path = os.path.join(CONF.tmp_path, 'user-data')
md_output_path = os.path.join(CONF.tmp_path, 'meta-data')
if CONF.prepare_configdrive:
cc_output_path = os.path.join(CONF.tmp_path, 'cloud_config.txt')
bh_output_path = os.path.join(CONF.tmp_path, 'boothook.txt')
# NOTE:file should be strictly named as 'user-data'
# the same is for meta-data as well
ud_output_path = os.path.join(CONF.tmp_path, 'user-data')
md_output_path = os.path.join(CONF.tmp_path, 'meta-data')
tmpl_dir = CONF.nc_template_path
utils.render_and_save(
tmpl_dir,
self.driver.configdrive_scheme.template_names('cloud_config'),
self.driver.configdrive_scheme.template_data(),
cc_output_path
)
utils.render_and_save(
tmpl_dir,
self.driver.configdrive_scheme.template_names('boothook'),
self.driver.configdrive_scheme.template_data(),
bh_output_path
)
utils.render_and_save(
tmpl_dir,
self.driver.configdrive_scheme.template_names('meta_data'),
self.driver.configdrive_scheme.template_data(),
md_output_path
)
tmpl_dir = CONF.nc_template_path
utils.render_and_save(
tmpl_dir,
self.driver.configdrive_scheme.template_names('cloud_config'),
self.driver.configdrive_scheme.template_data(),
cc_output_path
)
utils.render_and_save(
tmpl_dir,
self.driver.configdrive_scheme.template_names('boothook'),
self.driver.configdrive_scheme.template_data(),
bh_output_path
)
utils.render_and_save(
tmpl_dir,
self.driver.configdrive_scheme.template_names('meta_data'),
self.driver.configdrive_scheme.template_data(),
md_output_path
)
utils.execute('write-mime-multipart', '--output=%s' % ud_output_path,
'%s:text/cloud-boothook' % bh_output_path,
'%s:text/cloud-config' % cc_output_path)
utils.execute('genisoimage', '-output', CONF.config_drive_path,
'-volid', 'cidata', '-joliet', '-rock', ud_output_path,
md_output_path)
utils.execute(
'write-mime-multipart', '--output=%s' % ud_output_path,
'%s:text/cloud-boothook' % bh_output_path,
'%s:text/cloud-config' % cc_output_path)
utils.execute('genisoimage', '-output', CONF.config_drive_path,
'-volid', 'cidata', '-joliet', '-rock',
ud_output_path, md_output_path)
if CONF.prepare_configdrive or os.path.isfile(CONF.config_drive_path):
self._add_configdrive_image()
def _add_configdrive_image(self):
configdrive_device = self.driver.partition_scheme.configdrive_device()
if configdrive_device is None:
raise errors.WrongPartitionSchemeError(
@ -437,26 +453,31 @@ class Manager(object):
grub_timeout=CONF.grub_timeout)
gu.grub2_install(install_devices, chroot=chroot)
# FIXME(agordeev) There's no convenient way to perfrom NIC remapping in
# Ubuntu, so injecting files prior the first boot should work
with open(chroot + '/etc/udev/rules.d/70-persistent-net.rules',
'w') as f:
f.write('# Generated by fuel-agent during provisioning: BEGIN\n')
# pattern is aa:bb:cc:dd:ee:ff_eth0,aa:bb:cc:dd:ee:ff_eth1
for mapping in self.driver.configdrive_scheme.\
common.udevrules.split(','):
mac_addr, nic_name = mapping.split('_')
f.write('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
'ATTR{address}=="%s", ATTR{type}=="1", KERNEL=="eth*",'
' NAME="%s"\n' % (mac_addr, nic_name))
f.write('# Generated by fuel-agent during provisioning: END\n')
# FIXME(agordeev): Disable net-generator that will add new etries to
# 70-persistent-net.rules
with open(chroot +
'/etc/udev/rules.d/75-persistent-net-generator.rules',
'w') as f:
f.write('# Generated by fuel-agent during provisioning:\n'
'# DO NOT DELETE. It is needed to disable net-generator\n')
if CONF.fix_udev_net_rules:
# FIXME(agordeev) There's no convenient way to perfrom NIC
# remapping in Ubuntu, so injecting files prior the first boot
# should work
with open(chroot + '/etc/udev/rules.d/70-persistent-net.rules',
'w') as f:
f.write('# Generated by fuel-agent during provisioning: '
'BEGIN\n')
# pattern is aa:bb:cc:dd:ee:ff_eth0,aa:bb:cc:dd:ee:ff_eth1
for mapping in self.driver.configdrive_scheme.\
common.udevrules.split(','):
mac_addr, nic_name = mapping.split('_')
f.write('SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", '
'ATTR{address}=="%s", ATTR{type}=="1", '
'KERNEL=="eth*", NAME="%s"\n' % (mac_addr,
nic_name))
f.write('# Generated by fuel-agent during provisioning: END\n')
# FIXME(agordeev): Disable net-generator that will add new etries
# to 70-persistent-net.rules
with open(chroot +
'/etc/udev/rules.d/75-persistent-net-generator.rules',
'w') as f:
f.write('# Generated by fuel-agent during provisioning:\n'
'# DO NOT DELETE. It is needed to disable '
'net-generator\n')
# FIXME(kozhukalov): Prevent nailgun-agent from doing anything.
# This ugly hack is to be used together with the command removing

View File

@ -26,6 +26,7 @@ fuel_agent.drivers =
nailgun = fuel_agent.drivers.nailgun:Nailgun
nailgun_simple = fuel_agent.drivers.simple:NailgunSimpleDriver
nailgun_build_image = fuel_agent.drivers.nailgun:NailgunBuildImage
ironic = fuel_agent.drivers.nailgun:Ironic
[pbr]
autodoc_index_modules = True