From 0d6067258d09fdd47c95828e5e0e9b0f9987a529 Mon Sep 17 00:00:00 2001 From: Mark Asselstine Date: Mon, 9 Jan 2017 10:04:10 -0500 Subject: chef: remove the use of chef The use of chef was never complete, had isses with updating binary database files and had a cumbersome implementation. Since we are using Ansible in meta-overc we are dropping the use of chef here and will look to being at par with meta-overc by using Ansible if/when we get time to look at runtime configuration in meta-cloud-services. Signed-off-by: Mark Asselstine Signed-off-by: Bruce Ashfield --- meta-openstack/classes/openstackchef_inc.bbclass | 831 ----------------------- 1 file changed, 831 deletions(-) delete mode 100644 meta-openstack/classes/openstackchef_inc.bbclass (limited to 'meta-openstack/classes/openstackchef_inc.bbclass') diff --git a/meta-openstack/classes/openstackchef_inc.bbclass b/meta-openstack/classes/openstackchef_inc.bbclass deleted file mode 100644 index 91adb41..0000000 --- a/meta-openstack/classes/openstackchef_inc.bbclass +++ /dev/null @@ -1,831 +0,0 @@ -# openstackchef_inc.bbclass -# Copyright (c) 2014 Wind River Systems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONE INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# -# -#This class is a helper class for openstackchef.bbclass and should not be be -#inherited on it's own. It implements the functionalities used in -#openstackchef.bbclass -CHEFPN = "openstackchef" -#This variable is here to support legacy use of recipes that inherit this -#class. By default these recipes will be built without openstackchef support. -#Set this variable to 'yes' in your local.conf or similar to enable -#support for OPENSTACKCHEF. -OPENSTACKCHEF_ENABLED ?='' -#This variable is defined in most of the openstack services, however, -#it defaults to bare package name for packages that do not define it. -SRCNAME ?= "${BPN}" -#This is the base directory of where deploychef's templates files -#reside in the classes that inherit it. -CHEF_TEMPLATE_BASE="${D}${sysconfdir}/${CHEFPN}" -CHEF_PACKAGE_BASE="${WORKDIR}/package${sysconfdir}/${CHEFPN}" -CHEF_IMAGE_BASE="${D}${sysconfdir}" -CHEF_ROOTFS_BASE="${sysconfdir}/${CHEFPN}" -#These are the prefixs and suffixs to create chefsolo-like placeholders -ERB_PREFIX = "<%=node[:" -ERB_SUFFIX = "]%>" -#These prefix and suffix are used to create our default values -ERB_DEFAULT_PREFIX="default[" -ERB_DEFAULT_SUFFIX="]" -#Chefsolo template file extension -TEMPLATE_EXTENSION='.erb' -#Build deploychef package since this class has run-time and buil-time dependency -#on it -DEPENDS_${PN} += "${@bb.utils.contains('DISTRO_FEATURES', 'chef', 'deploychef', '', d)}" -RDEPENDS_${PN} += "${@bb.utils.contains('DISTRO_FEATURES', 'chef', 'deploychef', '', d)}" -CHEF_VERSION = '1' -#For classes that define a special substitution function, this variable is -#set by this class and specifies the file named passed back to these function -#for any special substitution. -CHEF_SERVICES_FILE_NAME ?='' - -#These are hard coded in the recipes files where they are used. -ADMIN_TENANT_NAME ?= 'admin' -DEMO_USER ?= 'demo' -#This is dafault value used by update-rc.d script at runtime when -#build-time update-rd.d class specifies INITSCRIPT_PARAMS as 'defaults' -CHEF_INITSCRIPT_PARAMS='defaults 20 10' - -def deploychef_services_default_sub_dict(d): - """Provides our placeholder/value substitution dictionary for global use - - This function returns as dictionary containing the default substitution pattern - as follows: - :: Name of placeholder variable - :: A tuple consisting of the place holder variable followed - by its default value - """ - sub_dict={} - #neutron - sub_dict['SERVICE_TENANT_NAME'] = ('%SERVICE_TENANT_NAME%' , - '${SERVICE_TENANT_NAME}') - sub_dict['SERVICE_PASSWORD'] = ('%SERVICE_PASSWORD%' , '${SERVICE_PASSWORD}') - - sub_dict['DB_USER'] = ('%DB_USER%', '${DB_USER}') - sub_dict['DB_PASSWORD'] = ('%DB_PASSWORD%' , '${DB_PASSWORD}') - sub_dict['CONTROLLER_IP'] = ('%CONTROLLER_IP%', '${CONTROLLER_IP}') - sub_dict['CONTROLLER_HOST'] = ('%CONTROLLER_HOST%', '${CONTROLLER_HOST}') - #nova - sub_dict['COMPUTE_IP'] = ('%COMPUTE_IP%', '${COMPUTE_IP}') - sub_dict['COMPUTE_HOST'] = ('%COMPUTE_HOST%', '${COMPUTE_HOST}') - sub_dict['LIBVIRT_IMAGES_TYPE'] = ('%LIBVIRT_IMAGES_TYPE%' , '${LIBVIRT_IMAGES_TYPE}') - sub_dict['OS_PASSWORD'] = ('%OS_PASSWORD%' , '${ADMIN_PASSWORD}') - sub_dict['SERVICE_TOKEN'] = ('%SERVICE_TOKEN%' , '${SERVICE_TOKEN}') - #swfit - sub_dict['ADMIN_TENANT_NAME'] = ('%ADMIN_TENANT_NAME%' , '${ADMIN_TENANT_NAME}') - sub_dict['ADMIN_USER'] = ('%ADMIN_USER%' , '${ADMIN_TENANT_NAME}') - sub_dict['ADMIN_PASSWORD'] = ('%ADMIN_PASSWORD%' , '${ADMIN_PASSWORD}') - sub_dict['DEMO_USER'] = ('%DEMO_USER%' , '${DEMO_USER}') - sub_dict['DEMO_PASSWORD'] = ('%DEMO_PASSWORD%' , '${ADMIN_PASSWORD}') - #ceilometer - sub_dict['CEILOMETER_SECRET'] = ('%CEILOMETER_SECRET%' , '${CEILOMETER_SECRET}') - - #keystone - sub_dict['TOKEN_FORMAT'] = ('%TOKEN_FORMAT%' , '${TOKEN_FORMAT}') - sub_dict['METADATA_SHARED_SECRET'] = ('%METADATA_SHARED_SECRET%' , '${METADATA_SHARED_SECRET}') - #cinder - sub_dict['CINDER_BACKUP_BACKEND_DRIVER'] = ('%CINDER_BACKUP_BACKEND_DRIVER%' , '${CINDER_BACKUP_BACKEND_DRIVER}') - #cloud-init - sub_dict['MANAGE_HOSTS'] = ('%MANAGE_HOSTS%' , '${MANAGE_HOSTS}') - sub_dict['HOSTNAME'] = ('%HOSTNAME%' , '${MY_HOST}') - #postgresql - sub_dict['DB_DATADIR'] = ('%DB_DATADIR%' , '${DB_DATADIR}') - #glance - sub_dict['GLANCE_DEFAULT_STORE'] = ('%GLANCE_DEFAULT_STORE%' , '${GLANCE_DEFAULT_STORE}') - - #barbican - sub_dict['BARBICAN_MAX_PACKET_SIZE'] = ('%BARBICAN_MAX_PACKET_SIZE%' , '${BARBICAN_MAX_PACKET_SIZE}') - #ceph - sub_dict['PUBLIC_IP'] = ('%PUBLIC_IP%' , '${CONTROLLER_IP}') - sub_dict['PRIVATE_IP'] = ('%PRIVATE_IP%' , '${MY_IP}') - sub_dict['PUBLIC_DOMAIN'] = ('%PUBLIC_DOMAIN%' , '${PUBLIC_DOMAIN}') - sub_dict['HOST_NAME'] = ('%HOST_NAME%' , '${MY_HOST}') - sub_dict['CEPH_BACKING_FILE_SIZE'] = ('%CEPH_BACKING_FILE_SIZE%' , '${CEPH_BACKING_FILE_SIZE}') - - #Most of the services have SERVICE_USER define but the values are different - service_user = d.getVar('SRCNAME', True) - if service_user: - service_user = service_user.upper() + '_SERVICE_USER' - sub_dict[service_user] = ('%SERVICE_USER%' , '${SRCNAME}') - return sub_dict - -#This variable is the default sets of substitutions common to most of the -#services in an openstack installation. It means this package is not completely -#agnostic but at the same time it gives us the added advantage of not repeating -#ourselves in the recipe/class files that inherits this class. -CHEF_SERVICES_DEFAULT_CONF_SUBS := "${@deploychef_services_default_sub_dict(d)}" - - -def deploychef_not_rootfs_class(d): - """Filter out rootfs related classes - - This function is used to help us selectively executes the creation of template - files and daemon start/stop list. It allows us to executes certain functions - when the recipe inheriting this class is related to rootfs creation. - """ - pkg = d.getVar('PN', True) or d.getVar('BPN', True) - #Skip test if recipe/class calling this class is related to rootfs image - #creation. - if 'image-' in pkg: - return False - else: - return True - -def deploychef_openstackchef_enabled(d): - """Find out if openstackchef class usage is enabled - - The variable OPENSTACKCHEF_ENABLED is use to support legacy functionality - by recipes inheriting this class. Assinging it an empty string disables - the functionality of this class for that recipe file. - This function helps us detect when this variable is set to an empty string. - """ - chef = d.getVar('OPENSTACKCHEF_ENABLED', True) - #Skip test if recipe/class calling this class is related to rootfs image - #creation. - if chef != '' : - return True - else: - return False - -def deploychef_make_startup_shutdown_list(d): - """Create list of services to start/stop and save them to file - - This function uses the update-rc.d environment variables defined - in the recipes/classes inheriting this class to create the - startup and shutdown services list as defined in the file. - This is important because, when we are replacing the configuration - files for the services, the services needs to be shutdown and - restarted after their configuration files are edited. - Therefore, the following variables must be defined by classes inheriting - this class. - - INITSCRIPT_PACKAGES: A list of init scripts - INITSCRIPT_PARAMS_x: The default start/stop priority for the above scripts - """ - - import os - if d.getVar('INITSCRIPT_PACKAGES') or d.getVar('INITSCRIPT_NAME'): - #script_list = d.getVar('INITSCRIPT_PACKAGES', 1) - script_list = d.getVar('INITSCRIPT_PACKAGES', True) or \ - d.getVar('INITSCRIPT_NAME', True) #Some package do not define INITSCRIPT_PACKAGES - msg="list of start/stop services: %s" % str(script_list) - bb.debug(2, msg) - base_dir = d.getVar('CHEF_TEMPLATE_BASE', 1 ) - if not os.path.exists(base_dir): - os.mkdir(base_dir) - startup_file = os.path.join(base_dir, d.getVar('SRCNAME', True) +'-startup-list') - shutdown_file = os.path.join(base_dir, d.getVar('SRCNAME', True) +'-shutdown-list') - msg ="Startup and shutdown files %s %s saved to %s" % \ - ( startup_file, shutdown_file, base_dir) - bb.note(msg) - try: - hStartup = open(startup_file, 'w') - hShutdown = open(shutdown_file, 'w') - for script_name in script_list.split(): - #Retrieve the default params for update-rc.d for this script - #INITSCRIPT_PARAMS_nova-api="defaults 30 10" - init_script_name ="INITSCRIPT_NAME_%s" % script_name - init_script_name = d.getVar(init_script_name, True) or \ - d.getVar('INITSCRIPT_NAME', True) - - script_params ="INITSCRIPT_PARAMS_%s" % script_name - script_params = d.getVar(script_params, True) or \ - d.getVar('INITSCRIPT_PARAMS', True) - #If only defaults is provided as parameter, then use our default priority - if not script_params or len(script_params.split()) < 3: - script_params = d.getVar('CHEF_INITSCRIPT_PARAMS', True) - if init_script_name: - #eg. start 20 5 3 2 . stop 80 0 1 6 . - startup_priority = shutdown_priority = '' - if script_params.find('stop') > 0: - start, stop = script_params.split('stop') - start = start.split() - stop = stop.split() - startup_priority = start[1] - shutdown_priority = stop[0] - elif script_params.find('stop') == 0: - start, stop = script_params.split('start') - start = start.split() - stop = stop.split() - startup_priority = start[0] - shutdown_priority = stop[1] - else: - #"defaults 20 10" - defaults = script_params.split() - startup_priority = defaults[1] - shutdown_priority = defaults[2] - #Arrange the script's startup/shutdown format as in rc.x - startup_string = "%s%s%s%s" % ('S', startup_priority, init_script_name, os.linesep) - shutdown_string = "%s%s%s%s" % ('K', shutdown_priority, init_script_name, os.linesep) - hStartup.write(startup_string) - hShutdown.write(shutdown_string) - msg = "%s %s registered for startup and shutdown in" % \ - (startup_string, shutdown_string) - bb.debug(2 , msg) - else: - msg = "The variables INITSCRIPT_PARAMS_%s or INITSCRIPT_PARAMS \ - are not set in %s, startup/shutdown list not created for %s: %s" \ - % (script_name, d.getVar('FILE', True), d.getVar('SRCNAME', True), script_params) - raise bb.build.FuncFailed(msg) - hStartup.close() - hShutdown.close() - except IOError as e: - bb.error("Error opening startup/shutdown files %s %s, %s %s" % \ - (startup_file, shutdown_file, d.getVar('FILE'), e)) - else: - msg = "The variable INITSCRIPT_PACKAGES is not set in %s, \ - startup/shutdown script will not be made for %s package" % \ - (d.getVar('FILE', True), d.getVar('SRCNAME', True)) - bb.build.FuncFailed(msg) - -def deploychef_make_substitutions(d, sub_dict, attr_filename, sed_filename): - """Make placeholder/value substitution in a file - - This function makes placeholder substitution into the file named - sed_filename and appends the default value for those substitution into - the file named attr_filename. - The substitution is based on sets of placeholder/value pair in the - dictionary called sub_dict. - :sub_dict: name, placeholder and value dictionary - :attr_filename: chef-solo attributes file name - :sed_filename: configuration or template file - """ - if attr_filename and sed_filename: - if type(sub_dict) is dict: - import os - import re - sHandle = open(sed_filename, 'r+') - lines_in_conf_file = sHandle.read() - #We only want to append to the list of defines needed by this class - hFile= open(attr_filename,'a+') - lines_in_file= hFile.read() - for key in sub_dict.keys(): - placeholder , replacement = sub_dict[key] - #Filter by placeholder so that our attribute file only include - #defines for class being built - if re.search(placeholder,lines_in_conf_file): - #Make the substitution to create a template file out of - #the configuration file or just replace placeholder in - #configuration file - if d.getVar('TEMPLATE_EXTENSION', True) in sed_filename: - #Format the default attributes as expected by chefsolo - #for template file. - attr_string = d.getVar('ERB_DEFAULT_PREFIX', True) - attr_string += r'"' + key - attr_string += r'"' + d.getVar('ERB_DEFAULT_SUFFIX', True) - attr_string +=' = ' + r'"' + replacement + r'"' - #Only write default values that do not yet exist in file - #if key not in lines_in_file: - if not re.search(key,lines_in_file): - hFile.write("%s%s" % (attr_string, os.linesep)) - #Replace the placeholders in the current file, with - #new_replacement - new_replacement = d.getVar('ERB_PREFIX') + key - new_replacement += d.getVar('ERB_SUFFIX') - lines_in_conf_file = re.sub(placeholder, new_replacement, lines_in_conf_file) - #Write template file to disk - sHandle.seek(0) - sHandle.truncate() - sHandle.write(lines_in_conf_file) - sHandle.close() - - hFile.close() - if False: - msg = "Cannot read/write to attributes file %s as expected:%s"\ - % (attr_filename, d.getVar('FILE')) - bb.build.FuncFailed(msg) - else: - msg = "The substitution dictionary variable sub_dict is not set %s as expected "\ - % d.getVar('FILE') - bb.error(msg) - else: - msg = "Null file names passsed to function %s %s "\ - % (d.getVar('FUNC'), d.getVar('FILE')) - bb.error(msg) - - - -def deploychef_make_templates( d, conf_tuple=tuple()): - """Create a template file out of a configuration file - - Using substitution placeholders and values in the substitution - dictionary declared as CHEF_SERVICES_DEFAULT_CONF_SUBS, this function - makes the substitution for all placeholders. If the file is a ruby template file, - it replaces the placeholders with a chefsolo expression; - thereby creating a chefsolo template file. - - :conf_tuple: List of configuration files - """ - - if len(conf_tuple): - import os, ast - base_dir = d.getVar('CHEF_TEMPLATE_BASE', 1 ) - attr_file = os.path.join(base_dir, d.getVar('SRCNAME', True) + '-attributes.rb') - msg ="Default attributes saved to %s" % attr_file - if os.path.exists(attr_file): - os.remove(attr_file) - bb.note(msg) - try: - for file_name in conf_tuple: - #If a special substitution function is defined for class - #inheriting this class, set the file name expected by special - #function before calling the function - special_func_name = d.getVar('CHEF_SERVICES_SPECIAL_FUNC') - if special_func_name: - bb.data.setVar('CHEF_SERVICES_FILE_NAME', file_name,\ - d) - bb.build.exec_func(special_func_name, d) - - #Make the necessary susbstitutions using the default - #substitutiin dictionary - sub_dict = d.getVar('CHEF_SERVICES_DEFAULT_CONF_SUBS', 1) - msg = "The variable %s is not set in %s as a dictionary as expected "\ - % ('CHEF_SERVICES_DEFAULT_CONF_SUBS', d.getVar('FILE')) - if sub_dict: - #Safely retrieve our python data structure - sub_dict = ast.literal_eval(sub_dict) - if type(sub_dict) is dict: - deploychef_make_substitutions(d, sub_dict, attr_file, file_name) - else: - raise bb.build.FuncFailed(msg) - else: - raise bb.build.FuncFailed(msg) - #Make the necessary susbstitutions using auxilliary dictionary - #if provided by inheriting class - sub_dict = d.getVar('CHEF_SERVICES_CONF_SUBS', 1) - if sub_dict: - sub_dict = ast.literal_eval(sub_dict) - msg = "The variable %s is not set in %s as a dictionary as expected "\ - % ('CHEF_SERVICES_CONF_SUB', d.getVar('FILE')) - if type(sub_dict) is dict: - pass - deploychef_make_substitutions(d, sub_dict, attr_file, file_name) - else: - bb.build.FuncFailed(msg) - except IOError as e: - bb.error("Could not write to attribute file %s: in %s, %s" % \ - (attr_file, d.getVar('FILE'), e)) - -def deploychef_copy_single_conf_file(d, dst_base, conf_file): - """Create a chef-solo template from an openstack configuration file - - This function copies a single configuration file (conf_file) - to destination directory (dst_dir) and return a tuple that contains - both the absolute path of the conf_file and the template files it was - copied as. - """ - if conf_file: - import shutil - import os - #Create the absolute path to configuration file since it's with relative - #to image directory - image_base = d.getVar('D', True) - if conf_file.startswith(os.sep): - conf_file=conf_file[1:] - abs_conf_path = os.path.join(image_base, conf_file) - - if os.path.exists(abs_conf_path): - dst_base = os.path.join(dst_base, os.path.dirname(conf_file)) - #make room for the template file about to be created - if not os.path.exists(dst_base): - os.makedirs(dst_base) - - abs_template_file = os.path.basename(conf_file) + \ - d.getVar('TEMPLATE_EXTENSION', True) + '.' + d.getVar('SRCNAME', True) - abs_template_file = os.path.join(dst_base, abs_template_file) - #Copy conf file as template file - shutil.copy(abs_conf_path, abs_template_file) - msg = "\nConf file: %s\n Copied to: %s \n"\ - % (abs_conf_path, abs_template_file) - bb.debug(2, msg) - return (abs_conf_path, abs_template_file) - else: - msg = "Configuration file: %s in %s does not \ - exist" % (abs_conf_path, d.getVar('FILE')) - raise bb.build.FuncFailed(msg) - else: - msg = "The specified configuration file destined for %s in %s is an empty string\n" \ - % (dst_base, d.getVar('FILE')) - raise bb.build.FuncFailed(msg) - - - -def deploychef_copy_conf_files(d): - """Copy openstack services' configuration files to be used as chef-solo templates - - Copy the configuration file(s) for the services under - ${D}${sysconfdir}/${CHEFPN}/. - The file(s) is/are assumed to be located in the images directory; ${D} - And evaluate all necessary substitution in the configuration file. - """ - abs_template_list = list() - abs_conf_list = list() - - #Retrieve our string of configuration files - conf_files = d.getVar('CHEF_SERVICES_CONF_FILES', True ) - #The template files that will be made from the configuration files will be - #copied with reference to this base directory. - dst_base = d.getVar('CHEF_TEMPLATE_BASE', True ) - if conf_files and len(conf_files.strip()): - conf_files = conf_files.split() - if len(conf_files) != 1: - for conf_file in conf_files: - abs_conf_path, abs_template_path = deploychef_copy_single_conf_file(d, \ - dst_base, conf_file) - if abs_template_path: - #Save the absolute path to the template file - abs_template_list.append(abs_template_path) - if abs_conf_path: - #Save the absolute path to the configuration file - abs_conf_list.append(abs_conf_path) - else: - abs_conf_path, abs_template_path = deploychef_copy_single_conf_file(d,\ - dst_base, conf_files[0]) - if abs_template_path: - #Save the absolute path to the template file - abs_template_list.append(abs_template_path) - if abs_conf_path: - #Save the absolute path to the template file - abs_conf_list.append(abs_conf_path) - #Since the recipes no longer do the substitution in the - #configuration files, let us do it for the configuration files - deploychef_make_templates(d, tuple(abs_conf_list)) - else: - msg = "The variable CHEF_SERVICES_CONF_FILES is not set" - msg += " in %s as a list of files as expected" % d.getVar('FILE', True) - #raise bb.build.FuncFailed(msg) - #No longer a requirement that all recipes inheriting this - #class must have a set of configuration files. - bb.debug(2,msg) - return tuple(abs_template_list) - -def deploychef_postinst_substitutions(d, sub_dict, postinst): - """Make value substitution in openstack services' postinstall scripts - - This function makes all necessary substitution in the 'setup' related postinsts - functions pgk_postinst_${PN}-setup. The substitution is base on entries in a - dictionary sub_dict. In addition it also updates the list of defined constansts - based on the values specified in dictionary or as specified by the recipe's - callback function. - - :sub_dict: name, placeholder and value substitution dictionary - :postinst: content of an openstack service's postinstall script - - """ - if postinst: - if type(sub_dict) is dict: - import re - base_dir = d.getVar('CHEF_PACKAGE_BASE', True) - attr_filename = os.path.join(base_dir, d.getVar('SRCNAME', True) + '-attributes.rb') - if os.path.exists(attr_filename): - hFile= open(attr_filename,'a+') - lines_in_file= hFile.read() - for key in sub_dict.keys(): - placeholder , replacement = sub_dict[key] - if replacement and ( re.search(placeholder, postinst) or \ - re.search(replacement, postinst)): - #If there is any remaining placeholder in the current string - #replace it. - new_replacement = d.getVar('ERB_PREFIX') + key - new_replacement += d.getVar('ERB_SUFFIX') - - updated_postinst = re.sub(placeholder, new_replacement, postinst) - #If the placeholder has been substituted, look for the - #substitution and replace it with our template value - updated_postinst = re.sub(replacement, new_replacement, updated_postinst) - #Update our attributes file with the updated replacement - #string - attr_string = d.getVar('ERB_DEFAULT_PREFIX', True) - attr_string += r'"' + key - attr_string += r'"' + d.getVar('ERB_DEFAULT_SUFFIX', True) - attr_string +=' = ' + r'"' + replacement + r'"' - #Only write default values that do not yet exist in file - #if key not in lines_in_file: - if not re.search(key,lines_in_file): - hFile.write("%s%s" % (attr_string, os.linesep)) - - postinst_msg= "placeholder %s \n replacement %s \n updated_postinst :\n %s \n" % \ - (placeholder, replacement, updated_postinst) - bb.debug(2, postinst_msg) - postinst = updated_postinst - hFile.close() - else: - msg = "The substitution dictionary variable sub_dict is not set %s as expected "\ - % d.getVar('FILE') - bb.build.FuncFailed(msg) - else: - msg = "Null string passsed to function %s %s "\ - % (d.getVar('FUNC'), d.getVar('FILE')) - bb.build.FuncFailed(msg) - return postinst - -def deploychef_update_package_postinsts(d): - """Make placeholder/value substitution in openstack postinstall scripts - - This function searches all the 'setup' related post-install scripts for - references to placeholders of interest; such as %CONTROLLER_IP%. - It replaces any such reference when it does find one with a placeholder - (<%=node[:CONTROLLER_IP]%>); that essentially converts the post-install - script to a chefsolo template. - """ - def update_postinst_package(pkg): - bb.debug(1, 'Updating placeholders in postinst for pkg_postinst_%s scripts' % pkg) - - ldata = bb.data.createCopy(d) - overrides = ldata.getVar("OVERRIDES", True) - - msg = "%s The override variable is %s" % (pkg, overrides) - bb.note(msg) - ldata.setVar("OVERRIDES", "%s:%s" % (pkg, overrides)) - - bb.data.update_data(ldata) - postinst = ldata.getVar('pkg_postinst', True) - if postinst: - #Make the necessary substitutions using the default - #substitution dictionary - overrides = d.getVar("OVERRIDES", True) - msg = "%s The override variable is %s :\n %s " % (pkg, overrides, postinst) - bb.note(msg) - sub_dict = d.getVar('CHEF_SERVICES_DEFAULT_CONF_SUBS', 1) - msg = "The variable %s is not set in %s as a dictionary as expected "\ - % ('CHEF_SERVICES_DEFAULT_CONF_SUBS', d.getVar('FILE')) - if sub_dict: - import ast - #Safely retrieve our python data structure - sub_dict = ast.literal_eval(sub_dict) - if type(sub_dict) is dict: - import re - updated_postinst = deploychef_postinst_substitutions(d, sub_dict, postinst) - #Replace the placeholders in postinst script if any - d.setVar('pkg_postinst_%s' % pkg, updated_postinst) - else: - raise bb.build.FuncFailed(msg) - else: - raise bb.build.FuncFailed(msg) - else: - msg= "pkg_postinst_%s does not exist for %s\n" % (pkg, str(ldata)) - bb.note(msg) - bb.build.FuncFailed(msg) - - packages = (d.getVar('PACKAGES', True) or "").split() - if packages != []: - for pkg in packages: - if pkg.endswith('setup'): - update_postinst_package(pkg) - -python populate_packages_append() { - - deploychef_update_package_postinsts(d) -} - -def deploychef_add_file_to_FILES_PN(d, conf_file=None): - """Add all directories under a file name to FILES_${PN} variable - - This function appends the name of the template file to the FILES_${PN}/${BPN} - bitbake variable to avoid QA warning about files built but not - added to rootfs. $CHEF_TEMPLATE_BASE/conf_file. Note that conf_file - is relative to the root filesystem as in /etc/neutron/neutron.conf - The template file will be located in /etc/${CHEFPN}/etc/neutron/neutron.conf.rb - Thefore, we need to make sure that all directories above the - template file are added to FILES_${PN} variable. - - :conf_file: a chef-solo template file - """ - import re - import os - #Perform an override so that we can update FILES_${PN} variables - ldata = bb.data.createCopy(d) - overrides = ldata.getVar("OVERRIDES", True) - pkg = d.getVar('PN', True) or d.getVar('BPN', True) - files = d.getVar('FILES_%s' % pkg, True) - pkg_files = "FILES_%s" % pkg - ldata.setVar("OVERRIDES", "%s:%s" % (pkg_files, overrides)) - bb.data.update_data(ldata) - - dest_base = d.getVar('CHEF_TEMPLATE_BASE', True) - pkg_imagedir = d.getVar('CHEF_ROOTFS_BASE', True) - #Add the packages image base directory if it does not already exist - if re.search(pkg_imagedir, files) == None: - #All the directory and all files in it - files = "%s %s" % ( files, pkg_imagedir) - files = "%s %s%s*" % ( files, pkg_imagedir, os.sep ) - d.setVar('FILES_%s' % pkg, files) - msg= "Updated FILES_%s: %s for base images dir" % (pkg, d.getVar('FILES_%s' % pkg, files)) - bb.debug(2,msg) - #All the files and all sub directory leading up to the package image base directory - if conf_file: - rel_basedir = os.path.dirname(conf_file) - if rel_basedir.startswith(os.sep): - rel_basedir = rel_basedir[1:] - rel_basedir = os.path.join(pkg_imagedir, rel_basedir) - if re.search(rel_basedir, files) == None: - files = "%s %s" % ( files, rel_basedir) - files = "%s %s%s*" % ( files, rel_basedir, os.sep ) - while rel_basedir.count(os.sep) > 4: - #Must be above /etc/chef/etc/ - rel_basedir_list = rel_basedir.split(os.sep) - rel_basedir = os.sep.join(rel_basedir_list[:-1]) - if re.search(rel_basedir, files) == None: - #All the directory and files in it - files = "%s %s" % ( files, rel_basedir) - files = "%s %s%s*" % ( files, rel_basedir, os.sep ) - bb.note(files) - bb.debug(2, files) - d.setVar('FILES_%s' % pkg, files) - msg= "Updated FILES_%s: %s " % (pkg, d.getVar('FILES_%s' % pkg, files)) - bb.debug(2,msg) - -def deploychef_update_FILES_PN_variable(d): - """Indicate that the created chef-solo templates should be packaged - - This function ensures that all the templates files which are based off - of configuration files exposed to this class are packaged up when they - are copied from the images directory to the various packages folders - This avoids the QA warning such as: - WARNING: For recipe python-neutron, the following files/directories were installed - but not shipped in any package: - """ - conf_files = d.getVar('CHEF_SERVICES_CONF_FILES', True ) - if conf_files and len(conf_files.strip()): - import shutil - import os - for conf_file in conf_files.split(): - deploychef_add_file_to_FILES_PN(d, conf_file) - else: - #Add the directory containing the start/stop scripts - deploychef_add_file_to_FILES_PN(d) - - -python populate_packages_prepend() { - - deploychef_update_FILES_PN_variable(d) -} - -#The sets of functions below are for post rootfs processing. Preparing files -#for chefsolo is a two stage process. First we must create the required files -#in the package's image directory; and this is mostly done by the functions -#above. -#And then we aggregate the files from their respective package directories -#and put them together for the deploychef package in the expected -#location. -CHEF_ROOT_DIR="${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}" -CHEF_CONF_DIR="${CHEF_ROOT_DIR}/${sysconfdir}" -INITD_DIR="${IMAGE_ROOTFS}/${sysconfdir}/init.d" -POSTINSTS_DIR="${IMAGE_ROOTFS}/${sysconfdir}/rpm-postinsts" -DEPLOYCHEF_DIR="${IMAGE_ROOTFS}/opt/deploychef" -DEPLOYCHEF_TEMPLATES_DIR="${DEPLOYCHEF_DIR}/cookbooks/openstack/templates/default" -ATTRIBUTES_DIR="${DEPLOYCHEF_DIR}/cookbooks/openstack/attributes" -ATTRIBUTES_FILE="${ATTRIBUTES_DIR}/default.rb" - -deploychef_copy_host_files() { - #The /etc/hosts & /etc/hostname files are written during the rootfs - #post process, therefore the only way of making templates out of them - #is to hook into the rootfs post process command. - if [ -f "${IMAGE_ROOTFS}/${sysconfdir}/hosts" ]; then - #Convert etc/hosts to chefsolo template - cp ${IMAGE_ROOTFS}/${sysconfdir}/hosts ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/${sysconfdir}/hosts.erb - sed -e "s,${CONTROLLER_IP},${ERB_PREFIX}CONTROLLER_IP${ERB_SUFFIX},g" -i \ - ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/${sysconfdir}/hosts.erb - sed -e "s,${CONTROLLER_HOST},${ERB_PREFIX}CONTROLLER_HOST${ERB_SUFFIX},g" -i \ - ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/${sysconfdir}/hosts.erb - - sed -e "s,${COMPUTE_IP},${ERB_PREFIX}COMPUTE_IP${ERB_SUFFIX},g" -i \ - ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/${sysconfdir}/hosts.erb - sed -e "s,${COMPUTE_HOST},${ERB_PREFIX}COMPUTE_HOST${ERB_SUFFIX},g" -i \ - ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/${sysconfdir}/hosts.erb - #Create an attribute file for /etc/hosts - attr_string="${ERB_DEFAULT_PREFIX}\"COMPUTE_IP\"${ERB_DEFAULT_SUFFIX} = \"${COMPUTE_IP}\"" - echo "$attr_string" > ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/hosts-attributes.rb - attr_string="${ERB_DEFAULT_PREFIX}\"COMPUTE_HOST\"${ERB_DEFAULT_SUFFIX} = \"${COMPUTE_HOST}\"" - echo "$attr_string" >> ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/hosts-attributes.rb - attr_string="${ERB_DEFAULT_PREFIX}\"CONTROLLER_IP\"${ERB_DEFAULT_SUFFIX} = \"${CONTROLLER_IP}\"" - echo "$attr_string" >> ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/hosts-attributes.rb - attr_string="${ERB_DEFAULT_PREFIX}\"CONTROLLER_HOST\"${ERB_DEFAULT_SUFFIX} = \"${CONTROLLER_HOST}\"" - echo "$attr_string" >> ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/hosts-attributes.rb - fi - - if [ -f "${IMAGE_ROOTFS}/${sysconfdir}/hostname" ]; then - #Convert etc/hostname to chefsolo template - cp ${IMAGE_ROOTFS}/${sysconfdir}/hostname ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/${sysconfdir}/hostname.erb - sed -e "s,${MY_HOST},${ERB_PREFIX}HOSTNAME${ERB_SUFFIX},g" -i \ - ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/${sysconfdir}/hostname.erb - #Create an attribute file for /etc/hostname - attr_string="${ERB_DEFAULT_PREFIX}\"HOSTNAME\"${ERB_DEFAULT_SUFFIX} = \"${MY_HOST}\"" - echo "$attr_string" > ${IMAGE_ROOTFS}/${sysconfdir}/${CHEFPN}/hostname-attributes.rb - fi -} - - -combine_services_daemons(){ - if [ -n $1 ]; then - file_suffix=$1 - rm -f ${DEPLOYCHEF_DIR}/$file_suffix - #combine the list of shutdown/startup scripts - find "${CHEF_ROOT_DIR}/" -name "*$file_suffix" 2> /dev/null | while read fname; do - service_cont=$(cat $fname) - for line in $service_cont; do - service=$(echo $line | awk -F"[SK][0-9]+" '{print $2}') - if [ -e ${INITD_DIR}/$service ]; then - echo $line >> ${DEPLOYCHEF_DIR}/$file_suffix - fi - done - done - fi -} - -#This function combines the attributes of all the sevices into -#a default.rb attributes file. -combine_services_attributes(){ - file_suffix='attributes.rb' - mkdir -p ${ATTRIBUTES_DIR}; rm -f ${ATTRIBUTES_FILE} 2>/dev/null - #combine the list of shutdown/starup scripts - find "${CHEF_ROOT_DIR}/" -name "*$file_suffix" 2> /dev/null | \ - while read fname; do - cat $fname | while read line_in_file; do - index=$(echo $line_in_file | awk -F'"' '{print $2}') - #Only append attributes that are not in the default.rb attributes file - if [ ! `grep -l $index ${ATTRIBUTES_FILE}` ]; then - echo $line_in_file >> ${ATTRIBUTES_FILE} - fi - done - done -} - -#This function copies the templates to deploychef directory from -#within the packages directories -copy_templates_in_place(){ - #copy rpm-postinsts and config templates into templates directory - mkdir -p ${DEPLOYCHEF_TEMPLATES_DIR} - #First copy all our configuration template files - if [ -d ${CHEF_CONF_DIR} ]; then - cp -rf ${CHEF_CONF_DIR} ${DEPLOYCHEF_TEMPLATES_DIR} - fi - #Now copy the rpm-postinsts files into cookbooks/templates/default/etc/ - if [ -d ${POSTINSTS_DIR} ]; then - cp -rf ${POSTINSTS_DIR} ${DEPLOYCHEF_TEMPLATES_DIR}/${sysconfdir} - #Move the files to base of the templates directory, where chef-solo - #expects them - cp -f ${POSTINSTS_DIR}/* ${DEPLOYCHEF_TEMPLATES_DIR}/. - fi - -} - -filter_node_dependent_templates(){ - if [ -d ${DEPLOYCHEF_TEMPLATES_DIR} ]; then - find "${DEPLOYCHEF_TEMPLATES_DIR}/" -name "*.erb*" 2> /dev/null | \ - while read fname; do - config_file=$(echo $fname | awk -F'/default' '{print $2}' | awk \ - -F'.erb' '{print $1}') - #If the base configuration file does not exist on this node - #remove it. - if [ ! -f ${IMAGE_ROOTFS}$config_file ]; then - rm -f "$fname" - else - #Move the file to the default template directory where - #chefsolo expect them - cp "$fname" "${DEPLOYCHEF_TEMPLATES_DIR}" - fi - done - fi -} - -#This function is our post rootfs hook, it enables -#us to do what we wish to do during rootfs creation process. -deploychef_rootfs_postprocess_commands() { - - if [ -n "${OPENSTACKCHEF_ENABLED}" ]; then - deploychef_copy_host_files - combine_services_daemons 'shutdown-list' - combine_services_daemons 'startup-list' - combine_services_attributes - copy_templates_in_place - filter_node_dependent_templates - else - #Let us delete the deploychef init script that runs - #chef-solo at boot-up from rootfs - rm -f ${INITD_DIR}/deploychef 2> /dev/null - fi - #We nolonger have need for /etc/${CHEFPN} directory on rootfs - #Not even at run-time - rm -rf "${CHEF_ROOT_DIR}" -} - -- cgit v1.2.3-54-g00ecf