Add meta-config via local.conf
This defines a new local.conf file that is designed to take the place of all
of the 'pass-through'[1] configuration options that have been defined in DevStack.
* new local.conf file can contain multiple config file settings to be
merged in to existing project config files
* localrc can be embedded into local.conf and will auto-extract if
localrc does not exist
* Adds functions get_meta_section(), get_meta_section_files(),
merge_config_file() and merge_config_group()
* Adds EXTRA_OPTS, EXTRA_BAREMETAL_OPTS, Q_DHCP_EXTRA_DEFAULT_OPTS and
Q_SRV_EXTRA_DEFAULT_OPTS to the deprecated warning list at the end of stack.sh
[1] Pass-through options are those that do not configure or change DevStack's behaviour
but simply set a value in a project config file. This includes most of the EXTRA_XXX_OPTS
configuration variables.
Change-Id: I367cadc86116621e9574ac203aafdab483d810d3
diff --git a/lib/config b/lib/config
new file mode 100644
index 0000000..6f686e9
--- /dev/null
+++ b/lib/config
@@ -0,0 +1,130 @@
+# lib/config - Configuration file manipulation functions
+
+# These functions have no external dependencies and the following side-effects:
+#
+# CONFIG_AWK_CMD is defined, default is ``awk``
+
+# Meta-config files contain multiple INI-style configuration files
+# using a specific new section header to delimit them:
+#
+# [[group-name|file-name]]
+#
+# group-name refers to the group of configuration file changes to be processed
+# at a particular time. These are called phases in ``stack.sh`` but
+# group here as these functions are not DevStack-specific.
+#
+# file-name is the destination of the config file
+
+# Save trace setting
+C_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Allow the awk command to be overridden on legacy platforms
+CONFIG_AWK_CMD=${CONFIG_AWK_CMD:-awk}
+
+# Get the section for the specific group and config file
+# get_meta_section infile group configfile
+function get_meta_section() {
+ local file=$1
+ local matchgroup=$2
+ local configfile=$3
+
+ [[ -r $file ]] || return 0
+ [[ -z $configfile ]] && return 0
+
+ $CONFIG_AWK_CMD -v matchgroup=$matchgroup -v configfile=$configfile '
+ BEGIN { group = "" }
+ /^\[\[.+|.*\]\]/ {
+ if (group == "") {
+ gsub("[][]", "", $1);
+ split($1, a, "|");
+ if (a[1] == matchgroup && a[2] == configfile) {
+ group=a[1]
+ }
+ } else {
+ group=""
+ }
+ next
+ }
+ {
+ if (group != "")
+ print $0
+ }
+ ' $file
+}
+
+
+# Get a list of config files for a specific group
+# get_meta_section_files infile group
+function get_meta_section_files() {
+ local file=$1
+ local matchgroup=$2
+
+ [[ -r $file ]] || return 0
+
+ $CONFIG_AWK_CMD -v matchgroup=$matchgroup '
+ /^\[\[.+\|.*\]\]/ {
+ gsub("[][]", "", $1);
+ split($1, a, "|");
+ if (a[1] == matchgroup)
+ print a[2]
+ }
+ ' $file
+}
+
+
+# Merge the contents of a meta-config file into its destination config file
+# If configfile does not exist it will be created.
+# merge_config_file infile group configfile
+function merge_config_file() {
+ local file=$1
+ local matchgroup=$2
+ local configfile=$3
+
+ [[ -r $configfile ]] || touch $configfile
+
+ get_meta_section $file $matchgroup $configfile | \
+ $CONFIG_AWK_CMD -v configfile=$configfile '
+ BEGIN { section = "" }
+ /^\[.+\]/ {
+ gsub("[][]", "", $1);
+ section=$1
+ next
+ }
+ /^ *\#/ {
+ next
+ }
+ /^.+/ {
+ split($0, d, " *= *")
+ print "iniset " configfile " " section " " d[1] " \"" d[2] "\""
+ }
+ ' | while read a; do eval "$a"; done
+
+}
+
+
+# Merge all of the files specified by group
+# merge_config_group infile group [group ...]
+function merge_config_group() {
+ local localfile=$1; shift
+ local matchgroups=$@
+
+ [[ -r $localfile ]] || return 0
+
+ for group in $matchgroups; do
+ for configfile in $(get_meta_section_files $localfile $group); do
+ if [[ -d $(dirname $configfile) ]]; then
+ merge_config_file $localfile $group $configfile
+ fi
+ done
+ done
+}
+
+
+# Restore xtrace
+$C_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End: