Running a shell command on multiple/all slaves from script console

2,849 views
Skip to first unread message

Omer Weissman

unread,
Dec 12, 2013, 4:33:37 AM12/12/13
to jenkins...@googlegroups.com
Hello, 

We are using Jenkins with multiple slaves (17 and soon more ), all are VBox Ubuntu guests. 
I want to execute an administrative shell script on all slaves using the script console in Jenkins manage. 
for example gathering mac addresses running ifconfig. 

I've tried to google the subject several times in the past couple of weeks, unfortunately with no answers. 
This is what I came up with so far : 

//def logger = ???? 
  
for (slave in hudson.model.Hudson.instance.slaves) { 
    println('Proceswsing Slave ' + slave.name); 
  
        def launcher = slave.createLauncher(); 
        
        def command = new hudson.util.ArgumentListBuilder(); 
        command.addTokenized("ifconfig | grep HWaddr"); 
    
        def ps = new hudson.Launcher.ProcStarter(); 
        ps = ps.cmds(command); 
        //ps = ps.stdout(logger);  
        
        def proc = launcher.launch(ps); 
  def retcode = proc.join(); 
  println("ret code="+retcode) 
  


but running this fails with the following exception : 

java.lang.NullPointerException 
        at hudson.Launcher.printCommandLine(Launcher.java:615) 
        at hudson.Launcher.maskedPrintCommandLine(Launcher.java:642) 
        at hudson.Launcher$LocalLauncher.launch(Launcher.java:764) 
        at hudson.Launcher$ProcStarter.start(Launcher.java:353) 
        at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:998) 
        at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:965) 
        at hudson.remoting.UserRequest.perform(UserRequest.java:118) 
        at hudson.remoting.UserRequest.perform(UserRequest.java:48) 
        at hudson.remoting.Request$2.run(Request.java:326) 
        at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72) 
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
        at java.lang.Thread.run(Thread.java:679) 


As I understand the ProcStarter needs to be specified with a TaskListener. 
How do I get the TaskListener that will take the output of the executed commands and print it below the script console? 

Also if you have a better way to achieve my goal I will be happy to hear. 

Thanks, 
Omer 

Dirk Heinrichs

unread,
Dec 12, 2013, 4:38:54 AM12/12/13
to jenkins...@googlegroups.com
Am 12.12.2013 10:33, schrieb Omer Weissman:

I want to execute an administrative shell script on all slaves using the script console in Jenkins manage. 

Did you try the Debian distributed shell (dsh)?

HTH...

    Dirk
--

Dirk Heinrichs, Senior Systems Engineer, Engineering Solutions
Recommind GmbH, Von-Liebig-Straße 1, 53359 Rheinbach
Tel: +49 2226 1596666 (Ansage) 1149
Email: d...@recommind.com
Skype: dirk.heinrichs.recommind
www.recommind.com

Omer Weissman

unread,
Dec 15, 2013, 7:05:36 AM12/15/13
to jenkins...@googlegroups.com, d...@recommind.com
Hi,

Thanks for the idea, I didn't try dsh, and I was not familiar with it.
But I still want to accomplish this through Jenkins Console, as dsh requires me to be in the same LAN or use VPN, and I want to be able to do it through the interface.

any ideas ?

Thanks,
Omer 

Les Mikesell

unread,
Dec 15, 2013, 11:18:57 AM12/15/13
to jenkinsci-users, d...@recommind.com
On Sun, Dec 15, 2013 at 6:05 AM, Omer Weissman <weis...@gmail.com> wrote:
>
> Thanks for the idea, I didn't try dsh, and I was not familiar with it.
> But I still want to accomplish this through Jenkins Console, as dsh requires me to be in the same LAN or use VPN, and I want to be able to do it through the interface.
>
> any ideas ?

I think the script console can only connect to one node at a time.
You could put you command in a matrix (multi-configuration) job and
select all the nodes, though.

--
Les Mikesell
lesmi...@gmail.com

Omer Weissman

unread,
Dec 16, 2013, 10:24:39 AM12/16/13
to jenkins...@googlegroups.com, d...@recommind.com
I was considering using the matix job, but it has a major flaw, it will be queued with the regular builds...we have one executor per slave and some of the jobs run for a long time ~30 minutes, so on part of the slaves it will wait for a long time in the queue.
I'm ok with t processing one by one from the script console, i'm just failing to do so :S
if I could only add an executor in the beginning of the build and remove it afterwards...

any ideas about the script ?

Les Mikesell

unread,
Dec 16, 2013, 11:10:26 AM12/16/13
to jenkinsci-users, d...@recommind.com
On Mon, Dec 16, 2013 at 9:24 AM, Omer Weissman <weis...@gmail.com> wrote:
> I was considering using the matix job, but it has a major flaw, it will be
> queued with the regular builds...we have one executor per slave and some of
> the jobs run for a long time ~30 minutes, so on part of the slaves it will
> wait for a long time in the queue.
> I'm ok with t processing one by one from the script console, i'm just
> failing to do so :S
> if I could only add an executor in the beginning of the build and remove it
> afterwards...

You can run more than one slave agent on a machine - which lets you
give them different node names and labels to control what they
execute.

> any ideas about the script ?

The script console runs groovy, which gives an execute() method to
quoted strings. Have you tried something like:
println "your_command".execute().text
in the script console? If the target is windows you may have to keep
in mind that some of the things you think are commands are build into
the cmd program.

--
Les Mikesell
lesmi...@gmail.com

Omer Weissman

unread,
Dec 16, 2013, 11:23:05 AM12/16/13
to jenkins...@googlegroups.com, d...@recommind.com
I have 17 slaves and soon will have more, so adding another maintenance agent per machine is a huge overhead...

I'm aware of the execute().text
as I understand, from the manage console it will only run on the master.
please see my original post for the loop trying to accomplish this.

many thanks 

Les Mikesell

unread,
Dec 16, 2013, 11:47:45 AM12/16/13
to jenkinsci-users, d...@recommind.com
On Mon, Dec 16, 2013 at 10:23 AM, Omer Weissman <weis...@gmail.com> wrote:
> I have 17 slaves and soon will have more, so adding another maintenance
> agent per machine is a huge overhead...

I don't find adding nodes to be difficult, especially if you start
them with ssh. Just add by copying an existing one and change the ssh
credentials. But it would add a lot of clutter on the jenkins web
page.

> I'm aware of the execute().text
> as I understand, from the manage console it will only run on the master.
> please see my original post for the loop trying to accomplish this.

I have a 'script console' link on every node page. If you don't have
that, maybe it comes with installing the groovy plugin. Commands
run there will run on the node. But, I don't know how to make a single
command iterate over the nodes - that is probably possible somewhere
in the API, though.

You could, of course run a script on the master that uses ssh (with
keys configured for passwordless access) to run the commands remotely
on the slaves without very much jenkins involvement. That would be a
more natural approach for me since I use ssh much more than java or
groovy.

--
Les Mikesell
lesmi...@gmail.com
Reply all
Reply to author
Forward
0 new messages