Tailf:exec not launching anything

Following the documentation, I tried to implement an action with an executable script:

  tailf:action myaction {
    tailf:exec "/tmp/myaction.py";
      "my action";

    // input;
    output {
      leaf var1 {
          "Some string";
        type string;
      leaf var2 {
          "Some other variable";
        type string;

Compilation works, but when in confd_cli, I always get an error with no details:

request myroot myaction
[error][2017-10-06 08:37:20]

The script is never run, even though it has executable privileges for all users.

I tried replacing the python script with a bash script, but had the same result. The empty error message doesn’t help much.

What did I miss?

What does the developer log say?

Nothing at all…

I had a look at the manual of confd.conf, I set up <developerLogLevel>trace</developerLogLevel>, confdLog is enabled on file, and so are developerLog and errorLog.

They don’t show anything relevant to my error…

I also tried launching confd with confd --verbose --foreground, but no luck.

Sure it will. The developer log will show that your osCommand produced an error when it was executed.
And so now it is up to you to debug that error in your script from your command line for example.

Here is a quick example as a reference:

$ pwd
$ ls
Makefile	confd.conf	config.yang	ping.py
$ cat config.yang
module config {
  namespace "http://tail-f.com/ns/example/config";
  prefix config;

  import tailf-common {
    prefix tailf;

  container config {
    list host {
      key name;
      leaf name {
        type string;
      tailf:action ping {
        tailf:exec "./ping.py" {
          tailf:args "-c $(context) -p $(path)";
          tailf:wd ".";
        input {
          leaf count {
            type int32;
            mandatory false;
            default "3";
        output {
          leaf result {
            type string;
$ cat ping.py
#!/usr/bin/env python
import sys
import os

x,y,host = sys.argv[4].split()

if (len(sys.argv) == 7):
    count = sys.argv[6]
    count = "1"

str = "ping -c %s %s"%(count, host)
result = os.popen(str).read()
print """result '
Invoked from %s
Ping to %s count %s:

%s'"""%(sys.argv[2], host, count, result)
$ make all start
$ confd_cli -u admin
admin connected from using console
# config
(config)# config host localhost        
(config)# commit
Commit complete.
(config)# do config host localhost ping count 1
Invoked from cli
Ping to localhost count 1:

PING localhost ( 56 data bytes
64 bytes from icmp_seq=0 ttl=64 time=0.045 ms

--- localhost ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.045/0.045/0.045/0.000 ms

Thanks. The problem is not inside my script, which executes without any errors if run. It’s confd that does not run the script at all.

I try to run the action via confd_cli and always get the blank error message described in my first message.

I tried:

  • moving the executable script to /tmp, giving full access to it to all users
  • enabling all logs in confd.conf
  • enabling the ‘trace’ log level

No luck…

So, what is the output, and the exit code (do ‘echo $?’ in the shell immediately after running it), of your script?

My script logs to a file as soon as it’s called and takes 20-30 seconds to finish its execution. It really seems that confd cannot even find the script, even if I specify it by its absolute path and make it executable by all users.

# /path/to/my/script/myscript.py
output1 'some string'
output2 'some other string'
# echo $?

# ll /path/to/my/script/myscript.py
-rwxr-xr-x 1 root root 9039 Oct  9 16:19 /path/to/my/script/myscript.py

Well, the output parameters output1/output2 don’t match the var1/var2 that you had in your YANG snippet, but that doesn’t explain the empty error and the script not being run at all… But maybe there are other differences - are you sure that you are updating, re-compiling, and restarting ConfD with, the right version of the module when you make changes? Can you run the ‘ping’ action in the intro/7-c_actions example? When I change the path in the YANG module there, I get the expected error in the CLI:

admin@mars% set config host localhost
[ok][2017-10-09 18:44:48]

admin@mars% request config host localhost ping count 1
Error: /nowhere/ping.pl: No such file or directory
[error][2017-10-09 18:45:01]

Yeah, I wrote output1/output2 on the spot, replacing my real variables. Hence the mismatch :slight_smile:

Anyways, I copied and pasted the ping example into my yang file, and I get the same blank error message as with my code.

Can it be a permission problem? How do I declare that a given user or user group can execute actions?

I update the model and restart confd properly. The prompt on confd_cli correctly autocompletes with the name of the action I want to perform.

What’s even more weird is that I just tried to run the action via netconf and I got “unknown element” error…

I think it would be better if you actually (if possible) ran the example, to reduce the number of unknowns… I wonder if there is something wrong with your ConfD installation - tailf:exec actions are run via the program $CONFD_DIR/lib/confd/lib/core/confd/priv/cmdwrapper - does it exist and is executable?[quote=“rick_r, post:9, topic:1580”]
Can it be a permission problem? How do I declare that a given user or user group can execute actions?
There is nothing that needs to be “declared” for that. You can control it via the AAA/NACM rules just like everything else, but the defaults should not prevent running actions (and those rules don’t differentiate between action-as-callback and action-as-executable).[quote=“rick_r, post:9, topic:1580”]
What’s even more weird is that I just tried to run the action via netconf and I got “unknown element” error…
What exactly was the “unknown element” (this should be inciuded in the info)? It might just be that you need to set /confdConfig/netconf/capabilities/actions/enabled to “true”.

That was the way to go. With the help of strace, I looked at the system calls that are executed when I run my action and it turned out that I didn’t have the file child_setup in my installation of Confd.

Works like a charm now! Thanks a lot!

I have a similar issue, how did you fix it exactly? I can’t find “child_setup” in the documentation, sorry.

Here is my attempt to run the action example:

ntc(config)# config host localhost
ntc(config-host-localhost)# commit
Commit complete.
ntc(config-host-localhost)# ping count 3 ?
Possible completions:
ntc(config-host-localhost)# ping count 3
Error: ./ping.pl: No such file or directory
ntc(config-host-localhost)# ping
Error: ./ping.pl: No such file or directory
ntc(config-host-localhost)# end
ntc@ntc:7-actions$ make start
### Killing any confd daemon and ARP confd agents
/home/ntc/confd-install/bin/confd --stop || true
connection refused (stop)
killall `pgrep -f "python ./action.py"` || true
10353: no process found
/home/ntc/confd-install/bin/confd -c confd.conf --addloadpath /home/ntc/confd-install/etc/confd
### * In one terminal window, run: tail -f ./confd.log
### * In another terminal window, run queries
###   (try 'make query' for an example)
### * In this window, the actions confd daemon now starts:
python ./action.py
register_done called

Ctrl-C pressed

from devel.log

<ERR> 19-Jul-2018::08:29:11.067 ntc confd[10360]: confd osCommand error: /home/ntc/confd-install/lib/confd/lib/core/confd/priv/cmdwrapper -I -p 4565 -i 0 -m 14 -G "27,1000" -c "/home/ntc" -U 13 -e  -N "admin" ./ping.pl Jy1jJyAnY2xpJyAnLXAnICdjb25maWcgaG9zdCBsb2NhbGhvc3QnICBjb3VudCAnMyc=: error: (non-fatal) failed to set secondary groups

<ERR> 19-Jul-2018::08:29:30.172 ntc confd[10360]: confd osCommand error: /home/ntc/confd-install/lib/confd/lib/core/confd/priv/cmdwrapper -I -p 4565 -i 1 -m 14 -G "27,1000" -c "/home/ntc" -U 13 -e  -N "admin" ./ping.pl Jy1jJyAnY2xpJyAnLXAnICdjb25maWcgaG9zdCBsb2NhbGhvc3QnICBjb3VudCAnMyc=: error: (non-fatal) failed to set secondary groups

<INFO> 19-Jul-2018::08:30:48.483 ntc confd[10360]: devel-c Worker closed daemon id: 0, worker id: 4, socket: {socket,<0.238.0>}

Also, I checked and see “$CONFD_DIR/lib/confd/lib/core/confd/priv/cmdwrapper” exists and is executable already.

ntc@ntc:priv$ ls -l
total 520
-rwxr-xr-x 1 ntc ntc  40416 Jun 26 09:15 cmdptywrapper
-rwxr-xr-x 1 ntc ntc  32488 Jun 26 09:15 cmdwrapper
-rw-r--r-- 1 ntc ntc  39559 Jun 26 09:15 confd_cfg.fxs
-rw-r--r-- 1 ntc ntc   1166 Jun 26 09:15 confd.fxs
-rw-r--r-- 1 ntc ntc    461 Jun 26 09:15 config.fxs
-rwxr-xr-x 1 ntc ntc   7664 Jun 26 09:15 crypt-hash
-rw-r--r-- 1 ntc ntc   7132 Jun 26 09:15 ietf-inet-types.fxs
-rw-r--r-- 1 ntc ntc   6943 Jun 26 09:15 ietf-yang-types.fxs
-rwxr-xr-x 1 ntc ntc  11032 Jun 26 09:15 ipc_drv.so
-rwxr-xr-x 1 ntc ntc 360448 Jun 26 09:15 mmap_schema
-rw-r--r-- 1 ntc ntc  10750 Jun 26 09:15 netconf.fxs

Any thoughts?