#!/bin/bash # Purpose: set config value ################################################################################ set -e set -u # support testsuite FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}" HELPER="${HELPER:-/usr/share/ngcp-ngcpcfg/helper/}" SCRIPTS="${SCRIPTS:-/usr/share/ngcp-ngcpcfg/scripts/}" if ! [ -r "${FUNCTIONS}"/main ] ; then printf "Error: %s/main could not be read. Exiting.\n" "${FUNCTIONS}">&2 exit 1 fi . "${FUNCTIONS}"/main ## functions {{{ help() { echo "Usage: ngcpcfg set " echo "Example: ngcpcfg set /etc/ngcp-config/config.yml general.maintenance=yes" } ## }}} [ "${#:-}" -ne 2 ] && (help >&2 ; exit 1) file="$1" data="$2" RC=0 [ -f "${file}" ] || (log_error "missing ${file}. Exiting." ; exit 1) [ -z "${data}" ] && ( log_error "missing data to set. Exiting." ; exit 1) log_debug "Received data: ${data}" option="${data/=*/}" value="${data/*=/}" [ -z "${option}" ] && ( log_error "missing option to set. Exiting." ; exit 1) [ -z "${value}" ] && ( log_error "missing value to set. Exiting." ; exit 1) log_debug "Saving option '${option}' value '${value}' into '${file}'" if [[ ${value} =~ ^\'.*\'$ ]] ; then log_debug "\$value is already quoted." elif [[ ${value} =~ ^[0-9]*$ ]] ; then log_debug "Not quoting \$value for integers." elif [[ ${value} =~ ^\[.*\]$ ]] ; then log_debug "Not quoting \$value for arrays." elif [[ ${value} =~ ^\{.*\}$ ]] ; then log_debug "Not quoting \$value for hashes." else log_debug "Quoting \$value to prevent further Perl errors." value="\"${value}\"" fi tmp=$(mktemp) log_debug "Temporary perl file: ${tmp}" cat > "${tmp}" << EOF use strict; use warnings; use YAML::XS; my \$file="${file}"; my \$yaml = YAML::XS::LoadFile("\$file"); my \$valref = \\\$yaml; for my \$component (split(/\\./, "${option}")) { if (ref(\$valref) eq 'SCALAR' && defined(\$\$valref)) { print STDERR ("Key resolved to a SCALAR at '\$component'; cannot continue.\n"); exit(1); } elsif (\$component =~ /^\\d+\$/ && (!defined(\$\$valref) || ref(\$\$valref) eq 'ARRAY')) { \$valref = \\\$\$valref->[\$component]; } elsif (\$component eq 'APPEND' && ref(\$\$valref) eq 'ARRAY') { \$valref = \\\$\$valref->[\$#{\$\$valref}+1]; } elsif (!defined(\$\$valref) || ref(\$\$valref) eq 'HASH') { \$valref = \\\$\$valref->{\$component}; } else { print STDERR ("Key resolved to a " . ref(\$\$valref) . " reference; refusing to overwrite.\n"); exit(1); } } if (!defined(\$\$valref) || ref(\$valref) eq 'SCALAR') { \$\$valref = ${value}; } elsif (ref(\$\$valref) eq 'ARRAY' && ref(${value}) eq 'ARRAY') { \$\$valref = ${value}; } elsif (ref(\$\$valref) eq 'HASH' && ref(${value}) eq 'HASH') { \$\$valref = ${value}; } else { print STDERR ("Key resolved to a " . ref(\$\$valref) . " reference; refusing to overwrite.\n"); exit(1); } YAML::XS::DumpFile(\$file, \$yaml); EOF log_debug "perl -wCSD \"${tmp}\" || RC=$?" perl -wCSD "${tmp}" || RC=$? if [ "${RC}" = "0" ]; then log_debug "ngcpcfg diff | tail -n +5 || true" ngcpcfg diff | tail -n +5 || true fi if [ -n "${DEBUG:-}" ] ; then log_debug "Not removing temporary file ${tmp}" else rm -f "${tmp}" fi exit ${RC} ## END OF FILE #################################################################