Run a remote command on all Jenkins slaves via Masters's script console

后端 未结 4 1750
执念已碎
执念已碎 2021-01-02 04:29

I want to run same shell command (very simple shell commands like ls) on all the UNIX slaves which are connected to the master by using the master\'s script co

相关标签:
4条回答
  • 2021-01-02 04:42
    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());
    }
    
    0 讨论(0)
  • 2021-01-02 04:44

    The pipeline looks something like this:

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

    and then is file generate_projects.groovy, where the actually DSL generation is:

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

    Beside the above generation of the jobs, you'll need to keep a list of jobs that were generated and add all its elements in "build-all" pipeline job, that will look something like:

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

    So when you run the pipeline, a job for each agent will be created, and all new created jobs will run in parallel. I use it for updating setup scenario.

    0 讨论(0)
  • 2021-01-02 04:52

    Pretty old thread.

    I managed the same situation in next way. I have a pipeline jobs that is doing next stages: - first it checks online agents (since they are physical machine it may happen to be down) using something like: for "(slave in hudson.model.Hudson.instance.slaves)..." - next stage is to create jobs for each found agent using DSL plugin and list_of_agents.each. Besides jobs for every online agent, it's created a job that will run all of them in parallel. Of course, the new created jobs contains the commands that I want to run on agents. When I run the pipeline, on all agents will run the same script/commands and output is returned to master pipeline job.

    0 讨论(0)
  • 2021-01-02 05:00

    Until the end, I don't use * to search the agents, but instead I'm reading and parsing their names. For example, if I want to run a job on every agent that has LINUX in name, I will do next:

    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 '
    
    
    
    0 讨论(0)
提交回复
热议问题