Local python check

CMK version: 2.2.0p23cre
OS version: Alma Linux 8.9
Client agent: 2.2.0p23
Client OS: Alma Linux 8.9

Got a python script which runs a command to check battery levels in some home automation gear.

From command line the script outputs this:

P "Batt-Doorbell_Battery_Level" pct=75;20:;10: Battery charge remaining.

Do I have the syntax wrong there? It looks okay to me but I cannot get the server to inventory the services. Running check_mk_agent on the client side the python script doesn’t seem to get called and the output never shows up.

I have others but the output only changes in the Name section and the actual value. I’m only worried about the battery getting below 20%, and go critical if it’s below 10%.

Running the script as root on the client system it works great. I’ve put it in /usr/lib/check_mk_agent/local/ and permissions are 755.

A test local script works great, only real difference is it happens to be a bash script.

ADDED: Tried using sys.stdout.write in the python instead of a basic print() statement, didn’t change the behavior.

If you call the script “manually” as root, how exactly are you doing that? Like

/usr/lib/check_mk_agent/local/my-script.py

?

Has the script a proper shebang line? That’s the first line in the script. It should look similar to

#!/usr/bin/env python

or

#!/usr/bin/env python3

The full path to the python binary is also ok, but it must be correct (e.g. #!/usr/bin/python3).

If that doesn’t help, then maybe the script crashes before it can output anything. Try running the agent in debug mode (issue check_mk_agent -d as root and better redirect the output):

check_mk_agent -d 1>out.txt 2>err.txt

If that doesn’t help either, then it’s probably an environment thing. The agent is called via a systemd unit and may have a different environment compared to the one from your shell.

The script has a good shebang line.

I think I just figured out the problem, if not the solution yet. My python script runs a command that relies on an ssh key to authenticate into the OpenHAB console and karaf instance. While it works great when run as root the check_mk_agent isn’t able to run as root.

The agent is set to run as root in the /etc/systemd/check_mk@.service file but it doesn’t appear to actually have full root rights.

There’s a cmk-agent user on the client, is that what user the system will see when the agent is run in a normal check process?

The agent controller runs everything with root privileges unless specified otherwise. BUT: It uses a different environment than the root user. So you might want to either emulate a different environment in your script using os.environ or just by specifying full paths to key files.

1 Like

What’s the difference between the root users environment and what the agent is running in?

I started this script with the thought of expanding it later and some ideas I had would probably be easier to accomplish in python. But I can always backtrack to a bash off it’ll be an easier way to get it done.

When I create a script as a local check…

#!/bin/bash
env > /tmp/env.txt
echo "0 \"My 1st service\" - This static service is always OK"

…the resulting text file looks like…

SHELL=/bin/sh
MK_VARDIR=/var/lib/check_mk_agent
MK_DEFINE_LOG_SECTION_TIME=_log_section_time() { "$@"; }
PWD=/usr/lib/check_mk_agent/local
LOGNAME=root
SYSTEMD_EXEC_PID=841696
_=/usr/bin/env
PYTHON3=python3
PYTHON2=
HOME=/root
MK_READ_REMOTE=true
INVOCATION_ID=2af12d06c72d4001af2a062a3f33e586
MK_BIN=/usr/bin
MK_CONFDIR=/etc/check_mk
MK_RUN_ASYNC_PARTS=false
USER=root
SHLVL=2
MK_LOGDIR=/var/log/check_mk_agent
MK_LIBDIR=/usr/lib/check_mk_agent
REMOTE=::ffff:5.9.192.155
LC_ALL=C.utf8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
OLDPWD=/
BASH_FUNC_run_mrpe%%=() {  descr="${1}";
 shift;
 PLUGIN="${1%% *}";
 OUTPUT="$(eval "${MK_DEFINE_LOG_SECTION_TIME}; _log_section_time $*")";
 STATUS="$?";
 printf "<<<mrpe>>>\n";
 printf "(%s) %s %s %s" "${PLUGIN##*/}" "${descr}" "${STATUS}" "${OUTPUT}" | tr \\n \\1;
 printf "\n";
 unset descr PLUGIN OUTPUT STATUS
}
BASH_FUNC_run_cached%%=() {  NAME="${1}";
 MAXAGE="${2}";
 REFRESH_INTERVAL="${3}";
 shift 3;
 OUTPUT_TIMEOUT=$((MAXAGE * 3));
 CREATION_TIMEOUT=$((MAXAGE * 2));
 _run_cached_internal "${NAME}" "${REFRESH_INTERVAL}" "${MAXAGE}" "${OUTPUT_TIMEOUT}" "${CREATION_TIMEOUT}" "$@"
}
BASH_FUNC_waitmax%%=() {  timeout "$@"
}

There might be differences by the path, the python interpreter used and some variables root has in the command line do not even exist.

We will update the troubleshooting section to reflect this better:

1 Like

Hi.

What’s about the line in local check:

P “Batt-Doorbell_Battery_Level” pct=75;20:;10: Battery charge remaining.

When you use option P, the watn and crit values need to be integers. From my point of view the representaion is a string “20:” instead of 20. Did you check this?

Rg, Christian

That is ok. It is the syntax to denote just lower levels. I recently blundered into the same trap.

  • Just a 20 means “WARN if value ≥ 20” (just an upper threshold)
  • A 20:30 means “WARN if value ≤ 20 OR value ≥ 30” (upper and lower threshold)
  • Just 20: means “WARN if value ≤ 20” (just a lower threshold)

More about this in the docs.

4 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed. Contact an admin if you think this should be re-opened.