History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: QB-4005
Type: Bug Bug
Status: Closed Closed
Resolution: Won't Fix
Priority: Major Major
Assignee: Robin Shen
Reporter: rani dharne
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
QuickBuild

Unable to get node assigned to step

Created: 28/Jul/23 04:40 PM   Updated: 17/Aug/23 11:18 PM
Component/s: None
Affects Version/s: 12.0.5
Fix Version/s: None

Original Estimate: Unknown Remaining Estimate: Unknown Time Spent: Unknown
Environment: Production -12.0.5


 Description  « Hide
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



 All   Comments   Work Log   Change History      Sort Order:
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?

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()

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);
}

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.

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);
}
}
  }
}

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.

rani dharne [04/Aug/23 08:50 AM]
Also this code is providing the workflows which have assigned to run on specific node only?

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

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.

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.

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");
}

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?

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);

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);
}
}


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");
}
}
}
}
}

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);
}