dockertelegraftelegraf-inputs-plugin

passing docker env variables to a script called by telegraf by inputs.exec plugin


Need help from docker and telegraf experts. I am trying to create a docker image that runs inputs.exec input telegraf plugin, the plugin runs a script exec_oracle_python.sh which calls the env variables defined in docker file.

Docker File:

FROM <redacted>/telegraf:latest

ENV username="user"
ENV password="123"
ENV sid="orcl"

COPY telegraf.conf /etc/telegraf/
COPY /telegraf.d/10-output.conf /etc/telegraf/telegraf.d/
COPY entrypoint.sh /entrypoint.sh
COPY py_script.py /py_script.py 
COPY exec_oracle_python.sh /exec_oracle_python.sh

RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends python3 python3-pip python3-setuptools python3-wheel && \
    rm -rf /var/lib/apt/lists/*

RUN pip3 install requests pyyaml

CMD ["/bin/sh", "-c", "echo ${username}"]
CMD ["--config-directory","/etc/telegraf/telegraf.d"]
ENTRYPOINT [ "/entrypoint.sh" ]

telegraf.conf file (only input plugin config is shown):

  [[inputs.exec]]
   commands = ["/exec_oracle_python.sh"]
#
#   ## Timeout for each command to complete.
    timeout = "5s"
#
#   ## measurement name suffix (for separating different commands)
    name_suffix = "_mycollector"
#
#   ## Data format to consume.
#   ## Each data format has it's own unique set of configuration options, read
#   ## more about them here:
#   ## https://github.com/influxdata/telegraf/blob/master/docs/DATA_FORMATS_INPUT.md
    data_format = "wavefront"

exec_oracle_python.sh file:

python3 py_script.py -u $username -p $password -s $sid

py_script.py file:

import time
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-u', '--user', help="Pass the username with SELECT_CATALOG_ROLE role granted", required=True)
parser.add_argument('-p', '--passwd', required=True)
parser.add_argument('-s', '--sid', help="SID to connect to", required=True)
args = parser.parse_args()

servcount = 10
t = int(time.time())
mydata = "error.count %d %d source=dev env=staging user=%s password=%s sid=%s" % (servcount, t, args.user, args.passwd, args.sid)
print (mydata)

entrypoint.sh script:

$ cat entrypoint.sh 
#!/bin/bash
set -e

if [ "${1:0:1}" = '-' ]; then
    set -- telegraf "$@"
fi

if [ $EUID -ne 0 ]; then
    exec "$@"
else
    # Allow telegraf to send ICMP packets and bind to privliged ports
    setcap cap_net_raw,cap_net_bind_service+ep /usr/bin/telegraf || echo "Failed to set additional capabilities on /usr/bin/telegraf"

    exec setpriv --reuid telegraf --init-groups "$@"
fi

I am getting following error when telegraf container is started;

$ sudo docker run wf-telegraf-python:test6
2022-07-18T19:11:36Z I! Using config file: /etc/telegraf/telegraf.conf
2022-07-18T19:11:36Z I! Starting Telegraf 1.22.0
2022-07-18T19:11:36Z I! Loaded inputs: exec
2022-07-18T19:11:36Z I! Loaded aggregators: 
2022-07-18T19:11:36Z I! Loaded processors: 
2022-07-18T19:11:36Z I! Loaded outputs: wavefront
2022-07-18T19:11:36Z I! Tags enabled: host=72d8b202e548
2022-07-18T19:11:36Z I! [agent] Config: Interval:1m0s, Quiet:false, Hostname:"72d8b202e548", Flush Interval:10s
2022-07-18T19:11:36Z E! [inputs.exec] Error in plugin: exec: fork/exec /exec_oracle_python.sh: exec format error for command '/exec_oracle_python.sh': 

If I hard code the env variables in py_script.py then telegraf runs fine. Is there a way to pass env variables to a script called by telegraf using input.exec plugin?

Thanks in advance for help!!


Solution

  • exec format error for command

    This can indicate that the shell script is missing a shebang at the beginning. In your case, the exec_oracle_python.sh file does not appear to have #!/bin/sh, #!/bin/bash, or something similar.

    edit: it seems this can also be due to creating a script in one operating system type (e.g. Windows and/or MacOS) and trying to run it in another (e.g. Linux/Unix). However, your script example is missing a shebang unless your copy omitted it.