<< Back to previous view

[QB-4005] Unable to get node assigned to step
Created: 28/Jul/23  Updated: 17/Aug/23

Status: Closed
Project: QuickBuild
Component/s: None
Affects Version/s: 12.0.5
Fix Version/s: None

Type: Bug Priority: Major
Reporter: rani dharne Assigned To: Robin Shen
Resolution: Won't Fix Votes: 0
Remaining Estimate: Unknown Time Spent: Unknown
Original Estimate: Unknown
Environment: Production -12.0.5


 Description   
Hi ,

 We are trying to get the node assigned to step. and to all workflows in our quickbuild environment.
but getting below error while using getNode function.
could you please help us.

 ERROR - Step 'master>get_nodes_QB_workflows' is failed: The step is not associated with any build.

Regards,
Rani Dharne



 Comments   
Comment by Robin Shen [ 29/Jul/23 12:24 AM ]
Can you please let me know the detailed reproducing steps? Like how your configurations are setup and where you can calling this script?
Comment by rani dharne [ 01/Aug/23 02:04 PM ]
Hi Robin,

We are using execute script type step in which written groovy script.
calling get node function but getting below error.
could you please provide any example of using this function.

Code-

import java.util.logging.Logger
import java.lang.Object
import com.pmease.quickbuild.BuildAwareJob;
import com.pmease.quickbuild.stepsupport.Step;
import com.pmease.quickbuild.grid.GridNode;

def lst_l = []
String step;
String node;

for (eachConf in system.configurationManager.getAll()) {
  for (eachStep in eachConf.getSteps()) {
    step = eachStep.value;
    logger.info(step);
if (step.equals("master"))
{
logger.info("step is master");
node = GridNode.getNode("master")
logger.info(node);
}
}
}

Error-
 ERROR - Step 'master>get_nodes_QB_workflows' is failed: groovy.lang.MissingMethodException: No signature of method: static com.pmease.quickbuild.grid.GridNode.getNode() is applicable for argument types: (java.lang.String) values: [master]
Possible solutions: getId(), getPort(), getToken(), setToken(java.lang.String), getAt(java.lang.String), getIp()
Comment by Robin Shen [ 01/Aug/23 10:53 PM ]
So you are trying to get node running master step of each configuration. However this is not possible, as node running a step can only be determined when a configuration actually runs. You can only get the node selection criteria before that. For instance calling step.nodeMatcher and then consult its properties.

Or you may get latest build of each configuration (this might be slow as it will query database for each configuration), and print the node used to run master step:

for (eachConf in system.configurationManager.getAll()) {
  def latestBuild = eachConf.latestBuild;
  if (latestBuild != null)
    logger.info(latestBuild.masterStep.nodeAddress);
}
Comment by rani dharne [ 02/Aug/23 06:02 AM ]
Hi Robin,

Thanks for your response.
Actually we are trying to get the configuration list where only single node is assigned , restricted to run on specific node only not from the resource group.
Is it possible to get this list.

as from the latestbuild list , anyhow we will be getting node whether it is restricted on specified node or getting selected from resource group.
Comment by Robin Shen [ 02/Aug/23 10:30 PM ]
I see. You can then use below script to do the job:

groovy:

for (eachConf in system.configurationManager.getAll()) {
  for (eachStep in eachConf.steps.values()) {
    if (eachStep.isMaster()) {
      def nodeMatcher = eachStep.nodeMatcher;
def className = nodeMatcher.getClass().getSimpleName();
if (className == "ServerNodeMatcher") {
logger.info(eachConf.pathName + "@server");
} else if (className == "BuildAgentMatcher") {
logger.info(eachConf.pathName + "@" + nodeMatcher.address);
}
}
  }
}
Comment by rani dharne [ 04/Aug/23 08:47 AM ]
Hi Robin,

This code is absolutely working fine.
but it will be good if you elaborate this code more. or provide me the link from which I can understand the functions used in this code snippet.
Need to understand this code to get help on mores such automations.
Comment by rani dharne [ 04/Aug/23 08:50 AM ]
Also this code is providing the workflows which have assigned to run on specific node only?
Comment by Robin Shen [ 04/Aug/23 09:32 PM ]
You may get more info of how to write the script from inline help at top right of the input field. In short, it is a groovy script (https://groovy-lang.org/), And all methods used here can be explained with QB javadoc:

https://build.pmease.com/build/5743/javadoc
Comment by Robin Shen [ 04/Aug/23 09:35 PM ]
It only covers the case where the step is assigned to run on server or particular agent explicitly. If it is assigned to run on particular node via script (the option "run if specified script evaluates to true"), it will not be able to detect that, as that is determined dynamically when step actually runs.
Comment by rani dharne [ 11/Aug/23 01:56 PM ]
Hi Robin,

The above code is absolutely working fine.
Further we are looking to set the node to other node or to resource group which we give as a input to script.

could you please suggest anything on this.
Comment by rani dharne [ 11/Aug/23 02:54 PM ]
Below is the code on which I am trying upon.

for (eachConf in system.configurationManager.getAll()) {
for (eachStep in eachConf.steps.values()) {
  if (eachConf.pathName.endsWith("test_workflow")){
    if (eachStep.isMaster()) {
    def nodeMatcher = eachStep.nodeMatcher;
    def className = nodeMatcher.getClass().getSimpleName();
    logger.info(nodeMatcher.address);
    logger.info("In If loop" + "-" + eachConf.pathName);
eachStep.nodeMatcher.setAddress("EMEASTOWB44");
logger.info("node has set");
}
Comment by Robin Shen [ 11/Aug/23 09:47 PM ]
So you simply want to set master step of all configurations ending with "etst_workflow" to run on specified node?
Comment by rani dharne [ 12/Aug/23 11:50 AM ]
hi Robin,

Test_workflow is the sample workflow I have taken for testing.
we wanted to change node for any workflow in Quickbuild as per our requirement to other node or to resource group of our choice
written below code. but the changes are not reflecting in test_workflow
please suggest.

import com.pmease.quickbuild.setting.step.nodematcher.BuildAgentMatcher;

for (eachConf in system.configurationManager.getAll()) {
for (eachStep in eachConf.steps.values()) {
  if (eachConf.pathName.endsWith("test_workflow")){
    if (eachStep.isMaster()) {
    def nodeMatcher = eachStep.nodeMatcher;
    def className = nodeMatcher.getClass().getSimpleName();
    logger.info(nodeMatcher.address);
    logger.info("In If loop" + "-" + eachConf.pathName);
    if (className == "BuildAgentMatcher") {
node = "EMEASTOWB44:8811";
logger.info("node has set" + eachStep.nodeMatcher.setAddress(node));
system.configurationManager.save(eachConf);
Comment by Robin Shen [ 13/Aug/23 02:27 AM ]
You may use below script to configure a step to run on paritcular agent or particular resource:

import com.pmease.quickbuild.setting.step.nodematcher.*;
import com.pmease.quickbuild.migration.*;

for (eachConf in system.configurationManager.getAll()) {
if (eachConf.pathName.endsWith("test")) {
def changed = false;
for (eachStep in eachConf.steps.values()) {
if (eachStep.isMaster()) {
// If you want to run the step on specified agent
eachStep.nodeMatcher = new BuildAgentMatcher();
eachStep.nodeMatcher.address = "someagent:8811";

// If you want to run the step on specified resource
eachStep.nodeMatcher = new HasResourceMatcher();
eachStep.nodeMatcher.resource = "someresource";

eachConf.stepDOMs[eachStep.name] = VersionedDocument.fromBean(eachStep);
changed = true;
}
}
if (changed)
system.configurationManager.save(eachConf);
}
}

Comment by rani dharne [ 17/Aug/23 12:06 PM ]
Hi Robin,

while testing above code getting error
Step 'master>set_nodes_QB_workflows' is failed: groovy.lang.MissingPropertyException: No such property: address for class: com.pmease.quickbuild.setting.step.nodematcher.HasResourceMatcher

Script:-

groovy:
import com.pmease.quickbuild.setting.step.nodematcher.*;
import com.pmease.quickbuild.setting.step.resourcematcher.*;
import com.pmease.quickbuild.migration.*;

String old_server_or_resource_group = vars.getValue("old_server_or_resource_group");
String new_server_or_resource_group = vars.getValue("new_server_or_resource_group");
String resource_group = vars.getValue("Selection_resource_group_or_node");

for (eachConf in system.configurationManager.getAll()) {
if (eachConf.pathName.endsWith("test_workflow")){
def changed = false;
for (eachStep in eachConf.steps.values()) {
if (eachStep.isMaster()) {
def nodeMatcher = eachStep.nodeMatcher;
def className = nodeMatcher.getClass().getSimpleName();
if (nodeMatcher.address == old_server_or_resource_group) {
logger.info("node to node");
// If you want to run the step on specified agent
eachStep.nodeMatcher = new BuildAgentMatcher();
eachStep.nodeMatcher.address = new_server_or_resource_group;
}
else if (nodeMatcher.resource == old_server_or_resource_group){
logger.info("resource group to resource group");
eachStep.nodeMatcher = new HasResourceMatcher();
eachStep.nodeMatcher.resource = new_server_or_resource_group;
}
else if (resource_group){
logger.info("node to resource group");
}
}
}
}
}
Comment by Robin Shen [ 17/Aug/23 11:18 PM ]
"address" property of "nodeMatcher" is only available when it is a agent node matcher. So please add relevant check before access its properties:

if (className == "BuildAgentMatcher") {
  logger.info("Running on agent: " + nodeMatcher.address);
} else if (className == "HasResourceMatcher") {
  logger.info("Running with resource: " + nodeMatcher.resource);
}
Generated at Thu May 16 19:34:02 UTC 2024 using JIRA 189.