Action script status issue for the child fixlet

i want to make the main fixlet failed / pass as per the child fixlet execution success / failure

i tried to capture the child fixlet status via rest api but i am not able to use if/ else statement at the end.

// Enter Run time parameters for master fixlet execution

action uses wow64 redirection {false}
action parameter query "hostname" with description "Please enter the hostname" with default value ""
action parameter query "masterfolder" with description "Please enter the master folder" with default value ""
action parameter query "fixletid" with description "Please enter the fixlet id" with default value ""


if {not exists folder (parameter "masterfolder")} 
folder create {parameter "masterfolder"}
endif 


parameter "besserver" = "{dns name}" 

parameter "folder" = "{value of setting "_BESRelay_HTTPServer_ServerRootPath" of client}" 

if {not exists folder (parameter "folder")} 

folder create "{parameter "folder"}" 

endif 

// Build XML to deploy a new action from the fixlet 

createfile until EOF
<?xml version="1.0" encoding="UTF-8"?>
<BES
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BES.xsd">
    <SourcedFixletAction>
        <SourceFixlet>
            <Sitename>test</Sitename>
            <FixletID>{parameter "fixletid"}</FixletID>
            <Action>Action1</Action>
        </SourceFixlet>
        <Target>
            <ComputerName>{parameter "hostname"}</ComputerName>
        </Target>
    </SourcedFixletAction>
</BES> 

EOF 

delete "{parameter "folder"}\action.xml" 

copy __createfile "{parameter "folder"}\action.xml" 

// Update the fixlet using IEM.exe 

parameter "iem" = "{parent folder of folder (value of setting "_BESRelay_HTTPServer_ServerRootPath" of client) as string & "\IEM CLI\iem.exe"}"  

wait cmd.exe /c ""{parameter "iem"}" login -q --server={parameter "besserver"} --user="bigfix" --password=XXXXX --masthead="{pathname of folder of main gather service & "\actionsite.afxm"}"" 

wait cmd.exe /c ""{parameter "iem"}" POST "{parameter "folder"}\action.xml" actions -q" > {parameter "masterfolder"}\child_action.txt

copy {parameter “masterfolder”}\child_action.txt {parameter “masterfolder”}\child_action1.txt

parameter "error"="{exists action whose (exit code of it = 0)}"

if {true}
exit {exit code of action}
else
exit 100
endif

Do you have the exert of the client log of the action script being executed?

I would personally not structure it like this - running commands in action scripts technically generates new processes, so hypothetically speaking by doing wait cmd.exe /c “”{parameter “iem”}" login in one process may easily mean that when you start the actual process you are no longer logged in (not sure if session carries over between different cmd processes). Even if it does though collecting exit code itself of individual processes is a nightmare! For example, your aim for parameter “error” is I would imagine to capture the status code of the iem.exe command BUT it won’t! It essentially will capture the status code of cmd.exe which since it will run, it won’t care of the iem.exe was successful or not (cmd.exe was successful so your status code = 0) - it’s all with the fact that you are spawning process from a process where return codes are not transferred back to the parent process when the child completes…IF I have to build what you are after, I would write the code of the API calls in Powershell where it does allow you to capture return codes of the posted outputs, create all your error checking and handling and then return what you want as exit code.

Lastly, I think you may have something missing in the If-statement anyway - If {true} will always evaluate the first entry, so what is the point of the else-statement…

1 Like

i tried with powershell to caputre the return code / status of the child action but when in the main fixlet i use if / else statement with dyamic folder it would work and do not allow me to use if /else statement.

when i use below code to make the main fixlet complete / failed it works from QnA action tab but does not work from action script ??

  parameter "error"="{{exists file "child_action.txt" of folder (parameter "masterfolder")}"

    if {parameter "error" = "True"}
    wait cmd.exe /c timeout 3 --> for success 

    else {parameter "error" = "False"}

    wait bin.sh  >> just to make the action status failed 

    endif

Off top of my head you need single curly bracket only here.

yes it worked in qna action script but throwing error in agent logs while running action

what kind of error do you see in the agent log when you run the line?

with single { , getting this error , when i use {{ it is going to false statement ,
When i run only snippet of the code it works fine but when i use with actul child action code it behave weird.

 ActionLogMessage: (action:8501) Action signature verified for Downloads
   ActionLogMessage: (action:8501) **Relevance substitution error.**
   ActionLogMessage: (action:8501) ending action
At 07:09:34 -0400 - mailboxsite (http://server:52311/cgi-bin/bfgather.exe/mailboxsite7510943)
   Not Relevant - master2-vj (fixlet:8501)
   ActionLogMessage: (action:8501) Action signature verified for Downloads
   ActionLogMessage: (action:8501) Relevance substitution error.
   ActionLogMessage: (action:8501) ending action
A

// Enter Run time parameters for master fixlet execution
action uses wow64 redirection {false}
action parameter query "hostname" with description "Please enter the hostname" with default value ""
action parameter query "masterfolder" with description "Please enter the master folder" with default value ""
action parameter query "fixletid" with description "Please enter the fixlet id" with default value ""

if {not exists folder (parameter "masterfolder")} 
folder create {parameter "masterfolder"}
endif 
parameter "besserver" = "{dns name}" 
parameter "folder" = "{value of setting "_BESRelay_HTTPServer_ServerRootPath" of client}" 
if {not exists folder (parameter "folder")} 
folder create "{parameter "folder"}" 
endif 
// Build XML to deploy a new action from the fixlet 
createfile until EOF
<?xml version="1.0" encoding="UTF-8"?>
<BES
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BES.xsd">
    <SourcedFixletAction>
        <SourceFixlet>
            <Sitename>test</Sitename>
            <FixletID>{parameter "fixletid"}</FixletID>
            <Action>Action1</Action>
        </SourceFixlet>
        <Target>
            <ComputerName>{parameter "hostname"}</ComputerName>
        </Target>
    </SourcedFixletAction>
</BES> 
EOF 
delete "{parameter "folder"}\action.xml" 
copy __createfile "{parameter "folder"}\action.xml" 
// Update the fixlet using IEM.exe 
parameter "iem" = "{parent folder of folder (value of setting "_BESRelay_HTTPServer_ServerRootPath" of client) as string & "\IEM CLI\iem.exe"}"  
wait cmd.exe /c ""{parameter "iem"}" login -q --server={parameter "besserver"} --user="bigfix" --password=XXXXX --masthead="{pathname of folder of main gather service & "\actionsite.afxm"}"" 
wait cmd.exe /c ""{parameter "iem"}" POST "{parameter "folder"}\action.xml" actions -q" > {parameter "masterfolder"}\child_action.txt

parameter "error"="{exists file "child_action.txt" of folder (parameter "masterfolder")}"
if {parameter "error" = "True"}
wait cmd.exe /c timeout 3
else {parameter "error" = "False"}
wait bin.sh
endif

Well, relevance substitution may have failed anywhere and it’s pretty lengthy script, so I would start re-building it…For example, leave only the parameters and folder creation and see if that works; then add the creation files; then the restapi call - just narrow down exactly where in the code is the relevance substitution error.

i tried all the ways , but dynamic folder seems having issue , when i provide static folder path it works

Is the folder getting created to start with if you leave just the first few commands in?

folder is getting created when i do not put if /else but when i see the condition it throws error.

aaah, hold on, I glanced past that… You can’t have else with condition! Else-statement is always unconditional:

if {some relevance}
do whatever
else
do something else
endif

If you do want another condition, then use elseif

if {some relevance}
do whatever
elseif {some other condition}
do something else
else
do nothing
endif

it would not help , pls execute my script and try if / else statement

if {parameter “error” = “True”}
wait cmd.exe /c timeout 3
else {parameter “error” = “False”}
wait bin.sh
endif

Whatever other problems you have, this is not valid actionscript . This snippet will be evaluated as

if {parameter “error” = “True”}
    wait cmd.exe /c timeout 3
else
    {parameter “error” = “False”}
    wait bin.sh
endif

This means that you are assigning the parameter “Error” a new value, but parameters are not variables - treat them as constants

1 Like

You’re hitting a pretty obscure edge case here. If you note from the client log, you’re getting a parameter substitution error during downloads, before the action has even begun to execute.

During the download phase, the client parses every piece of relevance in the action just in case that’s required for any downloads logic. But at this point, before execution, you haven’t yet created the output folder or log file, so you’ll get a “Singular Expression” error and the action won’t begin.

You could change all of your relevance substitutions to error-handle missing files or folders, but the easiest workaround is to include a Prefetch Block in the action, even if the block is empty. With a Pretch Block, the action only parses that block during the download phase, the rest of the relevance is not substituted until the action executes.

That said, this whole workflow you’re still trying to build is problematic. It depends on sending REST API credentials down to the client, with all the problems that secure credential storage entails. It’s risky from a security perspective. It also depends on the client having network access back to the root server so it can use those credentials - and in most cases your client should not have direct access to the root, as that exposes the server attack surface.

Instead you should use Server Automation or your own REST API calls from a dedicated server to send the action to clients, poll the server to wait for the action status, and then send a second action to client2. It’s easier to protect the credential and protect access to the root server if all the connections are coming from one machine instead of coming from any random client.

We do have a Professional Services organization as well that builds custom utilities, automations, and workflows like this under contract. Let me know if you’d like contract info to engage with them to build tools to your needs.

1 Like