Distributing and running scripts

Distributing and executing scripts remotely

It is possible to deliver and run complex scripts with qbee. The function used for this is file distribution. Please upload your files or scripts with the qbee file manager and follow the following steps. Then you can deliver and run scripts on any number of embedded remote edge devices. There is also a new function available now. If you run a script that causes output you are able to see up to 100 lines of that output in the log reports:

  1. Upload any files with the file manager. Please note the path.

  2. In the qbee app go to "Configure" and select "System->File Distribution".

    On the device tab select the group or device that is in scope. For more inofrmation please see the configuration management documentation.

  3. Start the actual file distribution definition:

    File Source:

    /show-uname.sh
    

    File Destination:

    /home/pi/show-uname.sh
    

    This plays out the script to the defined remote devices. If "command to run" is defined this command will be run anytime a new file is distributed.

    file-distribution-example

    When does this script get distributed and run?

    qbee checks if the file exists in the defined destination. If not it will be transfered. Both the file in the file manager and the file on the machine have a checksum. If the file manager file is replaced a new file distribution happens. Likewise, if the file on the target machine is changed or deleted this will also trigger a new file download and the changes will be overwritten with the original file from the file manager. Anytime there is a change the "command to run" will be executed again.

    Please check that the file distribution logic does not work against any other process

    This behaviour is very useful. But if a process on the target device is working against a file that is watched by qbee file distribution this can cause continuous file downloads. This will be seen in the logs.

  4. In order to do anything with the script the optional "Command to run" function can be used. Here commands can be chained using && and this opens up for a lot of options. In this case we do a simple operation and show what type of Linux is running. We distribute a script and run it with the "bash" command. Here is our example script:

    show-uname.sh

    #!/usr/bin/env bash
    
    echo "Your Linux environment is:"
    echo $(uname -a)
    
    exit 0
    

    Run the script in the bash shell with according permissions by using the following in "command to run" (see image above where to put this):

       bash /home/pi/show-uname.sh
    

    This runs the bash script. The output in the report logs will look like this when you select "show log". Please note that the script gest downloaded and run with the next agent run. If you do not change the script it only runs once.

    output-script

    It is also possible to use "python" or "python3" to run a python file. In addition, it is possible to run this with the rights of another user sudo -u user in order to avoid running a script as root. But then it needs to be made executable:

        chmod 755 /home/pi/show-uname.sh && sudo -u pi /home/pi/show-uname.sh
    

    The "command to run" always runs as root user and with root context. Therefore you need to specify if you want to execute things as a different user or expect different environment variables.

These commands will be triggered any time the file is distributed again

If the file in the file manager or the file on the target is replaced or changed these commands get run again. This means that for a regular device this script usually only runs once. If you want to trigger it again you can learn how to do this here.

It is possible to run the script with bash or alternatively you can work with chmod to make the script executable and then run it. See below:

When using chmod please read this!

If a script or a file is distributed the qbee agent will try to adjust the ownership rights according to the folder used. Sometimes additional chown or chmod commands are needed. If no templating is used this does not pose a problem. If templating is used please DO NOT chmod the file that is expanded as template. Below in point 5 you can see how you can get around this for scripts. If you need to do chmod on a config file you can copy it with cp or use something like this install -C -m 700 /some/temporary/collection/location/monitrc /etc/monit/monitrc.

  1. (Optional) It is possible to parametrize a scripts from the qbee UI. This is done by working with key-value pairs that are used as templates. In the following example we use a script that can control the Node-RED service. It should be able to start,stop,restart and disable or enable the service. In order to make this work you do the following:

    Create a script file and source a file with the templating variables. The variable $STATE contains the specific command ("restart").

    node-red-service.sh

    #!/usr/bin/env bash
    
    source /home/pi/node-red-service.conf
    
    sudo systemctl $STATE nodered.service
    

    This script is uploaded to the qbee file manager with the name node-red-service.js.

    Then the template file is created and uploaded as node-red-service.tmpl.

    node-red-service.tmpl

    # node-red service template for node-red-service script
    # run once trigger {{epoch}}
    
    # use start,stop,restart, disable, enable
    export STATE="{{service-state}}"
    

    This works in a way that variables can be exported and then they get sourced into the script. Key-value pairs that should be available in the UI are characterized through Mustache notation with double curly brackets {{key}}.

    File endings: .tmpl and .conf

    Template files are uploaded with a .tmpl ending and then in the file distribution it is defined into which name they expand. In this case the node-red-service.tmpl file will be expanded on the device into node-red-service.conf with the mustache notation replaced by the key-value pairs from the UI

    So the node-red-service.conf file that will end on the device looks as follows:

    node-red-service.conf

    # node-red service template for node-red-service script
    # run once trigger 1598358209
    
    # use start,stop,restart, disable, enable
    export STATE="restart"
    

Since both the template file and the script file are part of a single file distribution if any of those changes the command to run will be triggered and executed. So any change in the key-values will trigger the script to run. The "command to run" makes the script executable and then runs it:

chmod 755 /home/pi/node-red-service.sh && sudo -u pi /home/pi/node-red-service.sh  &

Why is there a {{epoch}} in the template comment and in the UI?

The qbee agent monitors the checksum of the file. If a key-value change is detected in the UI a new .conf file is written as the existing .conf file on the device is different than the new expanded .conf file on the server. Only if a file change occurs the "command to run" is triggered. So the systemctl in the script is only run when the STATE would change from "restart" to something else. This would make it impossible to run restart two times after another. The trick here is to put in the current epoch time (or any other unique variable) and just change that. Then a change is detected and the script is run. Thus we can run "restart" any number of times.