groovy 通过Masters的脚本控制台在所有Jenkins slaves上运行远程命令

8ehkhllq  于 2023-11-16  发布在  Jenkins
关注(0)|答案(5)|浏览(199)

我想运行相同的shell命令(非常简单的shell命令,如ls)的所有UNIX从连接到主通过使用主的脚本控制台。
如何使用Groovy实现这一点?
我想做这样的事情:Display Information About Nodes,但不是显示信息,我还想在每个从机上运行一些简单的UNIX命令并打印结果。

w1jd8yoj

w1jd8yoj1#

import hudson.util.RemotingDiagnostics;

print_ip = 'println InetAddress.localHost.hostAddress';
print_hostname = 'println InetAddress.localHost.canonicalHostName';

// here it is - the shell command, uname as example 
uname = 'def proc = "uname -a".execute(); proc.waitFor(); println proc.in.text';

for (slave in hudson.model.Hudson.instance.slaves) {
    println slave.name;
    println RemotingDiagnostics.executeGroovy(print_ip, slave.getChannel());
    println RemotingDiagnostics.executeGroovy(print_hostname, slave.getChannel());
    println RemotingDiagnostics.executeGroovy(uname, slave.getChannel());
}

字符串

gk7wooem

gk7wooem2#

直到最后,我都不使用 * 来搜索代理,而是阅读和解析它们的名称。例如,如果我想在名称中包含Linux的每个代理上运行作业,我将执行以下操作:

for (aSlave in hudson.model.Hudson.instance.slaves)
{
   /* take into account just agents with LINUX in name*/
   AGENT_NAME = aSlave.name
   if ( AGENT_NAME.contains('LINUX') )
   {
      /* you can check also if the agent is online or other attributes */

      /* Add agent name as label of the agent */ 
      AGENT_LABELS = aSlave.getLabelString() + " " + AGENT_NAME
      aSlave.setLabelString(AGENT_LABELS)

      /* For each found agent, create a job that will run on it */
      job('My_job_name_' + AGENT_NAME)
      {
          label(AGENT_NAME)
          steps {
               /* Do whatever you want here. 
                  This job will run just on this specific agent (due to label set) */
           }
      } 
   } /* end if */
} /* end for */  

/* If you want to run all jobs in parallel (every job on a specific agent), you can save all found agents in a list and then create one more pipeline job that will contain next line :

   ' parallel {
      b0: {build 'My_job_name_' + AGENT_NAME_LIST[0]},
      b1: {build 'My_job_name_' + AGENT_NAME_LIST[1]},
      ....
    }
    fastfail: false '

字符串

1l5u6lss

1l5u6lss3#

管道看起来像这样:

stages  {
      stage('Checkout repo') {
         steps  {
            //checkout what I need
         }
      }
      stage('Generate Jobs')  {
         steps  {
            jobDsl targets:'generate_projects.groovy',
         }
      }
      stage('Build Projects')  {
         steps  {
            build job: "build-all",
            propagate: true,
            wait: true
         }
      }
   }

字符串
然后是文件generate_projects.groovy,其中实际的DSL生成是:

for (agent in hudson.model.Hudson.instance.slaves) {
   if (!agent.getComputer().isOffline())  { // check that agent is not offline
      node = jenkins.model.Jenkins.instance.getNode(agent.name)  // get agent name
      agentIPs = node.computer.getChannel().call(new ListPossibleNames())
      agentIP = agentIPs[0]  // get agent IP
      
      //Create a job that will run on that specific agent
      jobName = FOLDER + '/<Job_name>' + agent.name     // need to create different names
      job(jobName)
      {
         label(agent.name)
         steps
         {
             shell(<shell script or commands that you want to run>)
         }
      }
   }
}


除了上面生成的作业之外,您还需要保留一个已生成作业的列表,并将其所有元素添加到“build-all”管道作业中,看起来像这样:

parallel(
   b0: {build '<Job_name>' + agent.name'},
   b1: {build '<Job_name>' + agent.name'},
   b2: {build '<Job_name>' + agent.name'},
   .....
)
failFast: false


因此,当您运行管道时,将为每个代理创建一个作业,并且所有新创建的作业将并行运行。

ijnw1ujt

ijnw1ujt4#

很老的线。
我在接下来的方式管理同样的情况。我有一个管道工作,正在做下一个阶段:-首先它检查在线代理(由于它们是物理机器,因此可能会发生停机)使用以下内容:为“(slave in hudson.model.哈德逊.instance.slaves).”-下一阶段是使用DSL插件和list_of_agents. each为每个找到的代理创建作业。除了为每个在线代理创建作业之外,它创建了一个作业,将并行运行所有这些作业。当然,新创建的作业包含我想在代理上运行的命令。当我运行管道时,所有代理将运行相同的脚本/命令,输出返回到主管道作业。

jmp7cifd

jmp7cifd5#

如果你需要使用管道或链式命令,这是另一种解决方案:(正如Graeme在评论中所建议的那样)

import hudson.util.RemotingDiagnostics;

def executeCmd(slave, cmd){
  process = "new ProcessBuilder( 'sh', '-c', \"$cmd\").redirectErrorStream(true).start()"
  script = "def proc = $process; proc.waitFor(); println proc.in.text";
  try{
    return RemotingDiagnostics.executeGroovy(script, slave.getChannel());
  } catch(Exception e){
    return "EXCEPTION:"+e.getMessage();
  }
}

remote_cmd="pwd | xargs ls -ld"
for (slave in hudson.model.Hudson.instance.slaves) {
  println slave.name  
  println executeCmd(slave, remote_cmd);
}

字符串

相关问题