Share This:

Building off of the Get the NSH Script Job Key, Name and Group location from a running NSH Script Job post, another useful piece of information is to get the JobRunId from inside the running NSH Script Job.


The first thought is to simply get the last JobRunKey from the JobKey I just retrieved.  That will probably work in most cases, but it is possible for multiple instances of a NSH Script Job to be running at the same time and the JobRun findLastRunKeyByJobKey may not return the RunKey of this run.  That might be a solution, if you know that there would only ever be a single instance of the Job running.


Let's instead have some more fun and figure out how we can be sure we are getting this run.  In the JobKey post, I found there are some UUIDs generated at run time for the execution of the script.  That seems interesting, however, as I found last time, those UUIDs don't seem to be something I can retrieve using the blcli.  But maybe I can use them in another way - I know that the generated UUID will be unique to this run.  I can show the UUID in the Job Run Log.  I can get the Job Run Log if I have the JobRunId/Key.  I don't have the Id or Key for this run (it's what I'm trying to get of course), but I can get the Id/Key of all the running jobs in the environment.  If I have the JobRunId/Key for all of the running jobs, I can loop through each one, and figure out if that run is this job by seeing if the UUIDs I'm echoing show up in the job run log.
Digging around in the unreleased blcli commands, I found a few promising commands: JobRun getAllJobRunProgress (which can be filtered by a role name, which reduces what I'm processing), JobRunProgress getJobRunId, which can act on the getAllJobRunProgress command output, Utility getCurrentRole, JobRun getLogItemsByJobRunId.

Here's the commented script:

# extract the UUIDs out of ${0}
myUUID="$(echo -n ${0} | sed "s/.*__//g;s/\.script.*//g")"
echo "myUUID: ${myUUID}"
# had to sleep for a bit for the log entry to get written
sleep 10
# get the current role id since I only need job runs that my role is running to find *this* job
blcli_execute Utility getCurrentRole
blcli_storeenv roleName
blcli_execute RBACRole findByName "${roleName}"
blcli_execute RBACRole getRoleId
blcli_storeenv roleId
# get all the running job ids
blcli_execute JobRun getAllJobRunProgress ${roleId}
blcli_execute JobRunProgress getJobRunId
blcli_execute Utility setTargetObject
blcli_execute Utility listPrint
blcli_storeenv jobRunIds
echo "Found running JobRunIds for role ${roleName}: $(tr '\n' ' ' <<< ${jobRunIds})"
# look at all the job runs for this role and find *this* run by looking for the uuid in the log messages
while read i
     echo "Processing job run id: ${i}"
     blcli_execute JobRun findById ${i}
     blcli_execute JobRun getJobType
     blcli_storeenv jobTypeId
     # only look at nsh script jobs
     if [[ ${jobTypeId} -eq 111 ]]
          # if there's more than ~30 log items, it won't be *this* run, because this run only should have a few log entries by now, speeds up processing
          blcli_execute JobRun getLogItemCountByJobRun ${i}
          blcli_storeenv logItemCount
          echo "JobRunId: ${i} LogItems: ${logItemCount}"
          if [[ ${logItemCount} -lt ${logItemMax} ]]
               blcli_execute JobRun getLogItemsByJobRunId ${i}
               blcli_storelocal logItems
               while read j
                    if  ( grep -q "${myUUID}" <<< "${j}" )
                         # run i, log line j has myuuid in it, must be me
                         echo "My JobRunId: ${i}"
                         break 2
               done <<< "$(awk 'NF' <<< "${logItems}")"
               echo "JobRunId: ${i} had: ${logItemCount} log items, too many"
done <<< "$(awk 'NF' <<< "${jobRunIds}" | sort -r)"
echo "My final JobRunId: ${myJobRunId}"

This works with Execute the script separately against each host (Type 1) and Execute the script once, passing the host list as a parameter to the script (Type 2) type of NSH Scripts.  For a type 1, even though the UUIDs for each target instance of the script will be different, the same jobRunId is retrieved.