See this article on Mender Hub.
apply-device-config
scripts are custom scripts, which can be installed into
the /usr/lib/mender-configure/apply-device-config.d
directory. They are then
executed by the Configure Update Module, with the expected configuration
parameters from the Mender server. In this way, you can extend Mender-Configure
to you needs and keep your device configuration in sync.
apply-device-config
scripts are simple shell (/bin/sh
) scripts, which take
one parameter: the JSON configuration values file. The script is then
responsible for parsing the value from the JSON configuration, and then apply
this to the system. See the examples in the examples section for
inspiration.
Scripts are always run with the entire configuration, even if there is no configuration available for this particular script. This means that you should be careful to either: use a default value, or have it simply act as a no-op, and then exit with success.
All scripts in /usr/lib/mender-configure/apply-device-config.d
are run in lexicographic order.
To get a feel for the main parts of a configuration script, let us dissect the time zone script:
#!/bin/sh
if [ $# -ne 1 ]; then
echo "Must be invoked with exactly one argument: The JSON configuration." 1>&2
exit 2
fi
CONFIG="$1"
if ! [ -e "$CONFIG" ]; then
echo "Error: $CONFIG does not exist." 1>&2
exit 1
fi
TIMEZONE="$(jq -r -e .timezone < "$CONFIG")"
return_code=$?
case $return_code in
0)
timedatectl set-timezone "$TIMEZONE"
exit $?
;;
1)
# Result was null, there is no timezone configuration, nothing to do.
echo "No timezone configuration found."
exit 0
;;
*)
exit $return_code
;;
esac
Note that this script relies on jq
to parse the JSON input, which might not be present in all Linux distributions by default. All scripts must have some way of parsing the input JSON.
#!/bin/sh
# Script which takes arguments from the configuration and runs COMMAND
if [ $# -ne 1 ]; then
echo "Must be invoked with exactly one argument: The JSON configuration." 1>&2
exit 2
fi
CONFIG="$1"
if ! [ -e "$CONFIG" ]; then
echo "Error: $CONFIG does not exist." 1>&2
exit 1
fi
ARGUMENTS="$(jq -r -e '."mender-demo-command-wrapper"' < "$CONFIG")"
return_code=$?
case $return_code in
0)
# Success, continue below.
:
;;
1)
echo "No mender-demo-command-wrapper configuration found." >&2
exit 0
;;
*)
exit $return_code
;;
esac
some-command "$ARGUMENTS"
return_code=$?
if [ $return_code -ne 0 ]; then
echo "Applying the command with configuration $ARGUMENTS failed" >&2
fi
exit $return_code
Since the scripts interpreter is controlled by the header shebang, you can configure your device using any interpreter present on your device.
As an example of this, let us write a simple configuration program in Python, following the three main steps outlined above:
#!/usr/bin/python
import json
import os.path
import subprocess
import sys
if len(sys.argv) != 2:
print("Must be invoked with exactly one argument: The JSON configuration.", file=sys.stderr)
sys.exit(1)
config=sys.argv[1]
if not os.path.exists(config):
print(f"Error: {config} does not exist.", file=sys.stderr)
sys.exit(1)
try:
configJSON = json.load(config)
timezone = configJSON["timezone"]
subprocess.run(["timedatectl", "set-timezone", timezone], check=True)
except json.JSONDecodeError as e:
print(f"Failed to parse the configuration JSON, error: {e}")
sys.exit(1)
except subprocess.CalledProcessError as e:
print(f"Setting the timezone with timedatectl failed with error: {e}")
sys.exit(1)
except Exception as e:
print(f"Failed with unhandled error: {e}")
sys.exit(1)
© 2024 Northern.tech AS