devstack/inc/ini-config
Yi Wang 698796f1ae Fix an issue in iniset function
Given the file to be configured, if user "stack" even doesn't have
read access, the result of configuration is not expected. iniset with
"-sudo" option will always create the section and the option which we
want to configure for each calling, no matter whether this section and
this option exist in the file or not. The root cause is the calling of
grep and ini_has_option in iniset don't use the "sudo" option.

Change-Id: I9d21322046b7be411c4c7c28fefc24894fa2e131
Signed-off-by: Yi Wang <yi.c.wang@intel.com>
2019-01-12 08:53:26 +08:00

454 lines
12 KiB
Bash

#!/bin/bash
#
# **inc/ini-config** - Configuration/INI functions
#
# Support for manipulating INI-style configuration files
#
# These functions have no external dependencies and no side-effects
# Save trace setting
INC_CONF_TRACE=$(set +o | grep xtrace)
set +o xtrace
# Config Functions
# ================
# Append a new option in an ini file without replacing the old value
# iniadd [-sudo] config-file section option value1 value2 value3 ...
function iniadd {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="-sudo "
shift
fi
local file=$1
local section=$2
local option=$3
shift 3
local values
values="$(iniget_multiline $file $section $option) $@"
iniset_multiline $sudo $file $section $option $values
$xtrace
}
# Comment an option in an INI file
# inicomment [-sudo] config-file section option
function inicomment {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
shift
fi
local file=$1
local section=$2
local option=$3
$sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ s|^\($option[ \t]*=.*$\)|#\1|" "$file"
$xtrace
}
# Get an option from an INI file
# iniget config-file section option
function iniget {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local file=$1
local section=$2
local option=$3
local line
line=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
echo ${line#*=}
$xtrace
}
# Get a multiple line option from an INI file
# iniget_multiline config-file section option
function iniget_multiline {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local file=$1
local section=$2
local option=$3
local values
values=$(sed -ne "/^\[$section\]/,/^\[.*\]/ { s/^$option[ \t]*=[ \t]*//gp; }" "$file")
echo ${values}
$xtrace
}
# Determinate is the given option present in the INI file
# ini_has_option [-sudo] config-file section option
function ini_has_option {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
shift
fi
local file=$1
local section=$2
local option=$3
local line
line=$($sudo sed -ne "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ p; }" "$file")
$xtrace
[ -n "$line" ]
}
# Add another config line for a multi-line option.
# It's normally called after iniset of the same option and assumes
# that the section already exists.
#
# Note that iniset_multiline requires all the 'lines' to be supplied
# in the argument list. Doing that will cause incorrect configuration
# if spaces are used in the config values.
#
# iniadd_literal [-sudo] config-file section option value
function iniadd_literal {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
shift
fi
local file=$1
local section=$2
local option=$3
local value=$4
if [[ -z $section || -z $option ]]; then
$xtrace
return
fi
# Add it
$sudo sed -i -e "/^\[$section\]/ a\\
$option = $value
" "$file"
$xtrace
}
# Remove an option from an INI file
# inidelete [-sudo] config-file section option
function inidelete {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
shift
fi
local file=$1
local section=$2
local option=$3
if [[ -z $section || -z $option ]]; then
$xtrace
return
fi
# Remove old values
$sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ d; }" "$file"
$xtrace
}
# Set an option in an INI file
# iniset [-sudo] config-file section option value
# - if the file does not exist, it is created
function iniset {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
local sudo_option=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
sudo_option="-sudo "
shift
fi
local file=$1
local section=$2
local option=$3
local value=$4
if [[ -z $section || -z $option ]]; then
$xtrace
return
fi
if ! $sudo grep -q "^\[$section\]" "$file" 2>/dev/null; then
# Add section at the end
echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
fi
if ! ini_has_option $sudo_option "$file" "$section" "$option"; then
# Add it
$sudo sed -i -e "/^\[$section\]/ a\\
$option = $value
" "$file"
else
local sep
sep=$(echo -ne "\x01")
# Replace it
$sudo sed -i -e '/^\['${section}'\]/,/^\[.*\]/ s'${sep}'^\('"${option}"'[ \t]*=[ \t]*\).*$'${sep}'\1'"${value}"${sep} "$file"
fi
$xtrace
}
# Set a multiple line option in an INI file
# iniset_multiline [-sudo] config-file section option value1 value2 value3 ...
function iniset_multiline {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
shift
fi
local file=$1
local section=$2
local option=$3
shift 3
local values
for v in $@; do
# The later sed command inserts each new value in the line next to
# the section identifier, which causes the values to be inserted in
# the reverse order. Do a reverse here to keep the original order.
values="$v ${values}"
done
if ! $sudo grep -q "^\[$section\]" "$file"; then
# Add section at the end
echo -e "\n[$section]" | $sudo tee --append "$file" > /dev/null
else
# Remove old values
$sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ { /^$option[ \t]*=/ d; }" "$file"
fi
# Add new ones
for v in $values; do
$sudo sed -i -e "/^\[$section\]/ a\\
$option = $v
" "$file"
done
$xtrace
}
# Uncomment an option in an INI file
# iniuncomment config-file section option
function iniuncomment {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
shift
fi
local file=$1
local section=$2
local option=$3
$sudo sed -i -e "/^\[$section\]/,/^\[.*\]/ s|[^ \t]*#[ \t]*\($option[ \t]*=.*$\)|\1|" "$file"
$xtrace
}
# Get list of sections from an INI file
# iniget_sections config-file
function iniget_sections {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local file=$1
echo $(sed -ne "s/^\[\(.*\)\]/\1/p" "$file")
$xtrace
}
# Set a localrc var
function localrc_set {
local file=$1
local group="local"
local conf="localrc"
local section=""
local option=$2
local value=$3
localconf_set "$file" "$group" "$conf" "$section" "$option" "$value"
}
# Check if local.conf has section.
function localconf_has_section {
local file=$1
local group=$2
local conf=$3
local section=$4
local sep
sep=$(echo -ne "\x01")
local line
line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
/\[${section}\]/p
}" "$file")
[ -n "$line" ]
}
# Check if local.conf has option.
function localconf_has_option {
local file=$1
local group=$2
local conf=$3
local section=$4
local option=$5
local sep
sep=$(echo -ne "\x01")
local line
if [[ -z "$section" ]]; then
line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
/${option}[ \t]*=.*$/p
}" "$file")
else
line=$(sed -ne "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
/\[${section}\]/,/\[\[.*\]\]\|\[.*\]/{
/${option}[ \t]*=.*$/p}
}" "$file")
fi
[ -n "$line" ]
}
# Update option in local.conf.
function localconf_update_option {
local sudo=$1
local file=$2
local group=$3
local conf=$4
local section=$5
local option=$6
local value=$7
local sep
sep=$(echo -ne "\x01")
if [[ -z "$section" ]]; then
$sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
s${sep}^\(${option}[ \t]*=[ \t]*\).*\$${sep}\1${value}${sep}
}" "$file"
else
$sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
/\[${section}\]/,/\[\[.*\]\]\|\[.*\]/s${sep}^\(${option}[ \t]*=[ \t]*\).*\$${sep}\1${value}${sep}
}" "$file"
fi
}
# Add option in local.conf.
function localconf_add_option {
local sudo=$1
local file=$2
local group=$3
local conf=$4
local section=$5
local option=$6
local value=$7
local sep
sep=$(echo -ne "\x01")
if [[ -z "$section" ]]; then
$sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep} a $option=$value" "$file"
else
$sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep},\\${sep}\[\[.*\]\]${sep}{
/\[${section}\]/ a $option=$value
}" "$file"
fi
}
# Add section and option in local.conf.
function localconf_add_section_and_option {
local sudo=$1
local file=$2
local group=$3
local conf=$4
local section=$5
local option=$6
local value=$7
local sep
sep=$(echo -ne "\x01")
$sudo sed -i -e "\\${sep}^\[\[${group}|${conf}\]\]${sep} {
a [$section]
a $option=$value
}" "$file"
}
# Set an option in a local.conf file.
# localconf_set [-sudo] config-file group conf-name section option value
# - if the file does not exist, it is created
function localconf_set {
local xtrace
xtrace=$(set +o | grep xtrace)
set +o xtrace
local sep
sep=$(echo -ne "\x01")
local sudo=""
if [ $1 == "-sudo" ]; then
sudo="sudo "
shift
fi
local file=$1
local group=$2
local conf=$3
local section=$4
local option=$5
local value=$6
if [[ -z $group || -z $conf || -z $option || -z $value ]]; then
$xtrace
return
fi
if ! grep -q "^\[\[${group}|${conf}\]\]" "$file" 2>/dev/null; then
# Add meta section at the end if it does not exist
echo -e "\n[[${group}|${conf}]]" | $sudo tee --append "$file" > /dev/null
# Add section at the end
if [[ -n "$section" ]]; then
echo -e "[$section]" | $sudo tee --append "$file" > /dev/null
fi
# Add option at the end
echo -e "$option=$value" | $sudo tee --append "$file" > /dev/null
elif [[ -z "$section" ]]; then
if ! localconf_has_option "$file" "$group" "$conf" "$section" "$option"; then
# Add option
localconf_add_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
else
# Replace it
localconf_update_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
fi
elif ! localconf_has_section "$file" "$group" "$conf" "$section"; then
# Add section and option in specified meta section
localconf_add_section_and_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
elif ! localconf_has_option "$file" "$group" "$conf" "$section" "$option"; then
# Add option
localconf_add_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
else
# Replace it
localconf_update_option "$sudo" "$file" "$group" "$conf" "$section" "$option" "$value"
fi
$xtrace
}
# Restore xtrace
$INC_CONF_TRACE
# Local variables:
# mode: shell-script
# End: