245 lines
6.6 KiB
Plaintext
245 lines
6.6 KiB
Plaintext
|
#!/usr/bin/env bash
|
||
|
|
||
|
# Copyright 2019 Mycroft AI Inc.
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
# you may not use this file except in compliance with the License.
|
||
|
# You may obtain a copy of the License at
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
# See the License for the specific language governing permissions and
|
||
|
# limitations under the License.
|
||
|
|
||
|
SOURCE="${BASH_SOURCE[0]}"
|
||
|
cd -P "$( dirname "$SOURCE" )"
|
||
|
DIR="$( pwd )"
|
||
|
script=${0}
|
||
|
script=${script##*/}
|
||
|
|
||
|
function help() {
|
||
|
echo "${script}: Mycroft configuration manager"
|
||
|
echo "usage: ${script} [COMMAND] [params]"
|
||
|
echo
|
||
|
echo "COMMANDs:"
|
||
|
echo " edit (system|user) edit and validate config file"
|
||
|
echo " reload instruct services to reload config"
|
||
|
echo " show (default|remote|system|user) display the specified setting file"
|
||
|
echo " set <var> set the variable (under USER)"
|
||
|
echo " get [var] display a particular variable"
|
||
|
echo " or all if no 'var' specified"
|
||
|
echo "Note: Use jq format for specifying <var>"
|
||
|
echo
|
||
|
echo "Examples:"
|
||
|
echo " ${script} edit user"
|
||
|
echo " sudo ${script} edit system"
|
||
|
echo " ${script} show remote"
|
||
|
echo " ${script} get"
|
||
|
echo " ${script} get enclosure.platform"
|
||
|
echo " ${script} set test.subvalue \"foo\" "
|
||
|
|
||
|
exit 1
|
||
|
}
|
||
|
|
||
|
################################################################
|
||
|
# Setup stuff based on the environment
|
||
|
|
||
|
VIEWER="nano --syntax=json --view"
|
||
|
if [ -z "$EDITOR" ] ; then
|
||
|
if [ $( which sensible-editor ) ] ; then
|
||
|
EDITOR="sensible-editor"
|
||
|
else
|
||
|
EDITOR="nano --syntax=json --tempfile"
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
if [ -z "$TEMP" ] ; then
|
||
|
TEMP="/tmp"
|
||
|
fi
|
||
|
|
||
|
function found_exe() {
|
||
|
hash "$1" 2>/dev/null
|
||
|
}
|
||
|
|
||
|
if found_exe tput ; then
|
||
|
GREEN="$(tput setaf 2)"
|
||
|
BLUE="$(tput setaf 4)"
|
||
|
CYAN="$(tput setaf 6)"
|
||
|
YELLOW="$(tput setaf 3)"
|
||
|
RESET="$(tput sgr0)"
|
||
|
HIGHLIGHT=${YELLOW}
|
||
|
fi
|
||
|
|
||
|
################################################################
|
||
|
# Utilities
|
||
|
|
||
|
function validate_config_file() {
|
||
|
if [ ! -f "$1" ] ; then
|
||
|
# A missing config file is valid
|
||
|
return 0
|
||
|
fi
|
||
|
|
||
|
echo -n ${BLUE}
|
||
|
|
||
|
# Remove any comments (lines starting with # or //) found in the file and
|
||
|
# Use jq to validate and output errors
|
||
|
sed 's/^\s*[#\/].*$//g' "$1" | sed '/^$/d' | jq -e "." > /dev/null
|
||
|
result=$?
|
||
|
|
||
|
echo -n ${RESET}
|
||
|
|
||
|
#xxx echo "RESULT=$result for $1"
|
||
|
return $result
|
||
|
}
|
||
|
|
||
|
_conf_file="~/.mycroft/mycroft.conf"
|
||
|
function name_to_path() {
|
||
|
case ${1} in
|
||
|
"system") _conf_file="/etc/mycroft/mycroft.conf" ;;
|
||
|
"user") _conf_file=$(readlink -f ~/.mycroft/mycroft.conf) ;;
|
||
|
"default") _conf_file="$DIR/../mycroft/configuration/mycroft.conf" ;;
|
||
|
"remote") _conf_file="/var/tmp/mycroft_web_cache.json" ;;
|
||
|
|
||
|
*)
|
||
|
echo "ERROR: Unknown name '${1}'."
|
||
|
echo " Must be one of: default, remote, system, or user"
|
||
|
exit 1
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
################################################################
|
||
|
|
||
|
function edit_config() {
|
||
|
name_to_path $1
|
||
|
validate_config_file $_conf_file
|
||
|
rc=$?
|
||
|
if [ $rc -ne 0 ] ; then
|
||
|
echo "${YELLOW}WARNING: ${RESET}Configuration file did not pass validation before edits."
|
||
|
read -p "Review errors above and press ENTER to continue with editing."
|
||
|
fi
|
||
|
|
||
|
if [ -f "${_conf_file}" ] ; then
|
||
|
cp "${_conf_file}" "${TEMP}/mycroft.json"
|
||
|
else
|
||
|
echo "{" > "${TEMP}/mycroft.json"
|
||
|
echo "}" >> "${TEMP}/mycroft.json"
|
||
|
fi
|
||
|
|
||
|
while [ 1 ] ; do
|
||
|
case $1 in
|
||
|
system | user)
|
||
|
# Allow user to edit
|
||
|
$EDITOR $TEMP/mycroft.json
|
||
|
;;
|
||
|
default | remote)
|
||
|
# View-only
|
||
|
echo "The default config shouldn't be changed, opening in View mode"
|
||
|
sleep 2
|
||
|
$VIEWER $TEMP/mycroft.json
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
cmp --quiet "${_conf_file}" "${TEMP}/mycroft.json"
|
||
|
rc=$?
|
||
|
if [ $rc -eq 0 ] ; then
|
||
|
echo "Configuration unchanged."
|
||
|
break
|
||
|
fi
|
||
|
|
||
|
# file was changed, validate changes
|
||
|
validate_config_file $TEMP/mycroft.json
|
||
|
if [ $? -ne 0 ] ; then
|
||
|
echo "${YELLOW}WARNING: ${RESET}Configuration file does not pass validation, see errors above."
|
||
|
echo "Press X to abandon changes, S to force save, any other key to edit again."
|
||
|
read -N1 -s key
|
||
|
else
|
||
|
key="S"
|
||
|
fi
|
||
|
|
||
|
case $key in
|
||
|
[Ss])
|
||
|
echo "Saving..."
|
||
|
mv $TEMP/mycroft.json $_conf_file
|
||
|
signal_reload_config
|
||
|
break
|
||
|
;;
|
||
|
[Xx])
|
||
|
# abandoning
|
||
|
break
|
||
|
;;
|
||
|
esac
|
||
|
|
||
|
done
|
||
|
}
|
||
|
|
||
|
function signal_reload_config() {
|
||
|
# Enter the Mycroft venv
|
||
|
source "$DIR/../venv-activate.sh" -q
|
||
|
|
||
|
# Post a messagebus notification to reload the config file
|
||
|
output=$(python -m mycroft.messagebus.send "configuration.updated" "{}")
|
||
|
}
|
||
|
|
||
|
function show_config() {
|
||
|
name_to_path $1
|
||
|
|
||
|
# Use jq to display formatted nicely (after stripping out comments)
|
||
|
sed 's/^\s*[#\/].*$//g' "${_conf_file}" | sed '/^$/d' | jq "."
|
||
|
}
|
||
|
|
||
|
function get_config() {
|
||
|
value=$1
|
||
|
if [[ ! $value =~ ^\..* ]] ; then
|
||
|
# Add the leading period if not included
|
||
|
value=".${value}"
|
||
|
fi
|
||
|
|
||
|
# Load all the configuration(s)
|
||
|
json_config=$( source "$DIR/../venv-activate.sh" -q && python -c "import json; from mycroft.configuration import Configuration; print(json.dumps(Configuration.get()))" )
|
||
|
|
||
|
# Read the given variable from the mix
|
||
|
echo ${json_config} | jq -r "${value}"
|
||
|
}
|
||
|
|
||
|
function set_config() {
|
||
|
# Set all overrides under the user configuration
|
||
|
value=$1
|
||
|
if [[ ! $value =~ ^\..* ]] ; then
|
||
|
# Add the leading period if not included
|
||
|
value=".${value}"
|
||
|
fi
|
||
|
|
||
|
jq "${value} = \"$2\"" ~/.mycroft/mycroft.conf > "${TEMP}/~mycroft.conf"
|
||
|
if [ $? -eq 0 ] ; then
|
||
|
# Successful update, replace the config file
|
||
|
mv "${TEMP}/~mycroft.conf" ~/.mycroft/mycroft.conf
|
||
|
signal_reload_config
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
_opt=$1
|
||
|
case ${_opt} in
|
||
|
"edit")
|
||
|
edit_config $2
|
||
|
;;
|
||
|
"reload")
|
||
|
signal_reload_config
|
||
|
;;
|
||
|
"show")
|
||
|
show_config $2
|
||
|
;;
|
||
|
"get")
|
||
|
get_config $2
|
||
|
;;
|
||
|
"set")
|
||
|
set_config "$2" "$3"
|
||
|
;;
|
||
|
|
||
|
*)
|
||
|
help
|
||
|
;;
|
||
|
esac
|