背景:要知道Jenkins是主从的,集群部署的时候,任务都是在从节点执行的。
需求:前边我们的插件都是在Master上执行的,怎么获取从节点Worksapce中的文件呢?或者如何在从节点执行任务呢?
获取从节点的VirtualChannel
VirtualChannel是Jenkins的类,其中有V call(Callable<V,T> callable)
以及Future<V> callAsync(final Callable<V,T> callable)
方法,分别是同步、异步调用远程方法。参数Callable可以定义在Slave上执行的方法,及返回值。
Builder实现Serializable接口
前面我们通过extends Builder implements SimpleBuildStep
来实现插件功能,其中perform
方法中有参数Run和Launcher。
其中launcher.getChannel()
以及run.getExecutor().getOwner()
可以获取到任务执行节点的对象应用。
实例:获取从节点Workspace下文件的内容
先看图:
任务中,我配置了两个build,第一个是shell,我输出了一段文字到paasImageVersion的文件中;第二个是我自定义的插件,现在我想在插件中获取paasImageVersion文件中的内容,文件在从节点,但插件在主节点。
实现如下:
/**
* 要在slave执行任务,必须实现Serializable接口
*/
public class PaasBuilder extends Builder implements SimpleBuildStep, Serializable {
/**
* 获取执行器,可能是slave节点,远程执行代码
*/
public String getRemoteFile(VirtualChannel channel, String path, TaskListener listener) {
Callable<String, ? extends Throwable> t = new Callable<String, Throwable>() {
@Override
public String call() throws Throwable {
BufferedReader reader = new BufferedReader(new FileReader(path));
String str = reader.readLine();
reader.close();
return str;
}
@Override
public void checkRoles(RoleChecker roleChecker) throws SecurityException {
}
};
try {
String call = channel.call(t);
return call;
} catch (Throwable throwable) {
throwable.printStackTrace();
listener.getLogger().println("slave err:" + throwable.getMessage());
}
return null;
}
@Override
public void perform(@NonNull Run<?, ?> run, @NonNull FilePath workspace, @NonNull EnvVars env, @NonNull Launcher launcher, @NonNull TaskListener listener) throws InterruptedException, IOException {
String path = env.get("WORKSPACE") + File.separator + "paasImageVersion";
imageVersion = this.getRemoteFile(launcher.getChannel(), path, listener);
}
@Extension
public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {
}