Extensions for noobs

Hello.
I am new to genie, and this caused some problems to me.
What am i trying to understand is how to work with extensions.
I am trying simple scenario:set variable from extension script and then print this var in the log.
I made a new preset with bootstrap event and made a new provision.
At first stage i made a simple new provision with simple script:
log('Extension test output: ');
And in the logs i see that all works fine:
2022-10-18T10:58:24.557Z [INFO] ::ffff:100.127.33.170 00259E-HG8247W5-48575443B8A8B1A0: Script: Extension test output:

After this i made a simple js script,placed in ext folder and checked that script belongs to genie user:

cat myext.js
function myfunc() {
            return("Hello");
                    }
exports.myfunc = myfunc;

And modified my test provision:

let myvar=ext("myext","myfunc");
log('Extension test output: '+myvar);

But after these steps i get in log
...faultCode="timeout" faultMessage="Extension timed out"

I just cant understand what is wrong. Extension script is very simple.
Can somebody explain what is wrong in my scenario?

have you tried the basic example provided in the documentation?

https://docs.genieacs.com/en/latest/extensions.html

it was the first one I ever tested and gave me the basic understanding on how extensions works.

your example looks good to me. While checking my ext permissions I have found it’s owned by root but Others readable. I have to guess permissions are not really an issue, but it’s worth checking.

also don’t forget about checking the logs at journalctrl -f (Debian)

It does not look good to me. Its missing the second param which is the callback that needs to be called when all the information is ready to return to the provision script. This is why @egor.gr is getting the timeout message.

The return procedure is not acceptable in extension script?

I have a little success with running extension.
But now there is a problem with reading local file.
I am trying to search if some text file contains serial number and return the result.
The new script is:

function checkonu(args, callback) {
let sn = args[0];
let onures="";
var fs = require("fs"), searchString = "ZTEEQLYN5C00002";
fs.readFile("/opt/genieacs/ext/onus.txt", function(err, content) {
    if (err) throw err;
             onures=content.indexOf(searchString)>-1 ? "has string" : "does not have string";
                      });
callback(null, onures);
}
exports.checkonu = checkonu;

File /opt/genieacs/ext/onus.txt belongs to

-rw-r--r-- 1 genieacs genieacs 16 Oct 19 13:08 onus.txt
The problem is that its like script doesnt search string in file.
However if i harcode variable onures to some value i see this value in the logs.
For example if after line
onures=content.indexOf(searchString)>-1 ? "has string" : "does not have string";
i add
onures="SomeTestValue"
I see in log(provision script is set to log onures variable) “SomeTestValue”
But if script remains as it is, in the logs i see that onures remains empty in the logs.
Am i missing some additional permissions to onus.txt or extensions from geanie cannot read files on filesystem?

Sorry
The problem was in cycles and conditions.
In other words callback was called out of conditions blocks
Working variant of script is

function checkonu(args, callback) {
let sn = args[0];
let onures="11";
const fs = require('fs');

fs.readFile('onus.txt', 'utf8', (err, data) => {
  if (err) {
        let onures=err;
        callback(null,onures);
                  return;
                              }
                                            console.log(data);
                                            onures=data;
                                            console.log(onures);
                                            callback(null,onures);
                                                          });
}
exports.checkonu = checkonu;

No, you have to call the callback when done.

A couple of things, your extension script file should end in .js, not .txt. Your callback in the if err condition is wrong. The error code/value/data is the first param to the callback. Here is a cleaned up and corrected version of your latest script:

function checkonu(args, callback) {
    let sn = args[0];
    let onures = "11";
    const fs = require('fs');

    fs.readFile('onus.txt', 'utf8', (err, data) => {
        if (err) {
            callback(err);

            return;
        }

        console.log(data);

        callback(null, data);
    });
}

exports.checkonu = checkonu;