无法使用插件访问 Jenkins slave 上的文件
Cannot access file on Jenkins slave with plugin
通过我自己的插件,我需要知道一个文件在Jenkins slave 的工作空间中是否存在。但是找不到文件,而它确实存在于slave上
artifactsToDeploy = workingDir.act(new FilesDeployerCallable(listener, pairs, artifactoryServer, credentials,
repositoryKey, propertiesToAdd,
artifactoryServer.createProxyConfiguration(Jenkins.getInstance().proxy),configurator.getProductKey(),configurator.getArtifactoryKey(), configurator.getBuildType() ,configurator.getRpmParameters(),build,configurator.issendFcmPayload(), configurator.getModule(), configurator.getTaxonomy()));
}
private static class FilesDeployerCallable implements FilePath.FileCallable<List<Artifact>> {
/**
*
*/
private static final long serialVersionUID = 1L;
private final String repositoryKey;
private BuildListener listener;
private Multimap<String, String> patternPairs;
private ArtifactoryServer server;
private Credentials credentials;
private ArrayListMultimap<String, String> buildProperties;
private ProxyConfiguration proxyConfiguration;
private String artifactKey;
private String buildType;
private String module;
private String taxonomy;
private RpmParameters rpmParameters;
private final AbstractBuild build;
private boolean sendFcmPayload;
private EnvVars env;
public FilesDeployerCallable(BuildListener listener, Multimap<String, String> patternPairs,
ArtifactoryServer server, Credentials credentials, String repositoryKey,
ArrayListMultimap<String, String> buildProperties, ProxyConfiguration proxyConfiguration,String productKey,String artifactKey, String buildType, RpmParameters rpmParameters, AbstractBuild build, boolean sendFcmPayload, String module, String taxonomy) throws IOException, InterruptedException {
this.listener = listener;
this.patternPairs = patternPairs;
this.server = server;
this.credentials = credentials;
this.repositoryKey = repositoryKey;
this.buildProperties = buildProperties;
this.proxyConfiguration = proxyConfiguration;
this.artifactKey = artifactKey;
this.buildType = buildType;
this.module = module;
this.taxonomy = taxonomy;
this.rpmParameters = rpmParameters;
this.build = build;
this.sendFcmPayload = sendFcmPayload;
this.env = build.getEnvironment(listener);
}
java.io.IOException: remote file operation failed:
/jenkins/slaveworkspace/workspace/githubMigration at
hudson.remoting.Channel@44434cf3:master-replicated:
java.io.IOException: Unable to serialize
hudson.FilePath$FileCallableWrapper@2ca3869b at
hudson.FilePath.act(FilePath.java:977) at
hudson.FilePath.act(FilePath.java:959) at
dj.pib.productivity.generic.GenericArtifactsDeployer.deploy(GenericArtifactsDeployer.java:148)
at
dj.pib.productivity.generic.ArtifactoryGenericConfigurator.tearDown(ArtifactoryGenericConfigurator.java:352)
at hudson.model.Build$BuildExecution.doRun(Build.java:171) at
hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:533)
at hudson.model.Run.execute(Run.java:1759) at
hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43) at
hudson.model.ResourceController.execute(ResourceController.java:89)
at hudson.model.Executor.run(Executor.java:240) Caused by:
java.io.IOException: Unable to serialize
hudson.FilePath$FileCallableWrapper@2ca3869b at
hudson.remoting.UserRequest.serialize(UserRequest.java:169) at
hudson.remoting.UserRequest.(UserRequest.java:63) at
hudson.remoting.Channel.call(Channel.java:750) at
hudson.FilePath.act(FilePath.java:970) ... 9 more Caused by:
java.io.NotSerializableException: hudson.model.FreeStyleBuild at
java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at
java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at
java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at
java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547)
at
java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508)
at
java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at
java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
at
java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at hudson.remoting.UserRequest._serialize(UserRequest.java:158) at
hudson.remoting.UserRequest.serialize(UserRequest.java:167) ... 12
more Collecting metadata...
我做错了什么?
编辑 1:好的,我看到问题是我在 filesDeployerCallable 中传递 AbstractBuild 构建,它不可序列化,但我需要它来做我做的事情。它确实给了我一个警告(抽象是原始类型,应该参数化)。我如何参数化它?它在 hudson.model.abstractModel
要回答问题如何查明文件是否存在于从站,从主站调用workspace.child("relative/path/to/my.file").exists()
应该就足够了。隐藏本地和远程文件之间的差异是 FilePath
存在的原因。
有几种方法可以解决 Jenkins 模型对象不可序列化的问题。
- 在master上保留逻辑,在slave上发送小任务(
Callable
s)。更容易确保这些任务足够简单,它们永远不需要 Jenkins 模型对象。使用 hudson.Launcher
和 hudson.FilePath
属于这一类。
- 在发送
Callable
到 slave 之前只提取可序列化的信息。例如,如果您只需要一个构建编号,则无需传输整个构建对象。
- 使用对象 proxies 因此只有域对象的远程代理会出现在从站上,并且所有方法调用都将通过通道分派。
通过我自己的插件,我需要知道一个文件在Jenkins slave 的工作空间中是否存在。但是找不到文件,而它确实存在于slave上
artifactsToDeploy = workingDir.act(new FilesDeployerCallable(listener, pairs, artifactoryServer, credentials,
repositoryKey, propertiesToAdd,
artifactoryServer.createProxyConfiguration(Jenkins.getInstance().proxy),configurator.getProductKey(),configurator.getArtifactoryKey(), configurator.getBuildType() ,configurator.getRpmParameters(),build,configurator.issendFcmPayload(), configurator.getModule(), configurator.getTaxonomy()));
}
private static class FilesDeployerCallable implements FilePath.FileCallable<List<Artifact>> {
/**
*
*/
private static final long serialVersionUID = 1L;
private final String repositoryKey;
private BuildListener listener;
private Multimap<String, String> patternPairs;
private ArtifactoryServer server;
private Credentials credentials;
private ArrayListMultimap<String, String> buildProperties;
private ProxyConfiguration proxyConfiguration;
private String artifactKey;
private String buildType;
private String module;
private String taxonomy;
private RpmParameters rpmParameters;
private final AbstractBuild build;
private boolean sendFcmPayload;
private EnvVars env;
public FilesDeployerCallable(BuildListener listener, Multimap<String, String> patternPairs,
ArtifactoryServer server, Credentials credentials, String repositoryKey,
ArrayListMultimap<String, String> buildProperties, ProxyConfiguration proxyConfiguration,String productKey,String artifactKey, String buildType, RpmParameters rpmParameters, AbstractBuild build, boolean sendFcmPayload, String module, String taxonomy) throws IOException, InterruptedException {
this.listener = listener;
this.patternPairs = patternPairs;
this.server = server;
this.credentials = credentials;
this.repositoryKey = repositoryKey;
this.buildProperties = buildProperties;
this.proxyConfiguration = proxyConfiguration;
this.artifactKey = artifactKey;
this.buildType = buildType;
this.module = module;
this.taxonomy = taxonomy;
this.rpmParameters = rpmParameters;
this.build = build;
this.sendFcmPayload = sendFcmPayload;
this.env = build.getEnvironment(listener);
}
java.io.IOException: remote file operation failed: /jenkins/slaveworkspace/workspace/githubMigration at hudson.remoting.Channel@44434cf3:master-replicated: java.io.IOException: Unable to serialize hudson.FilePath$FileCallableWrapper@2ca3869b at hudson.FilePath.act(FilePath.java:977) at hudson.FilePath.act(FilePath.java:959) at dj.pib.productivity.generic.GenericArtifactsDeployer.deploy(GenericArtifactsDeployer.java:148) at dj.pib.productivity.generic.ArtifactoryGenericConfigurator.tearDown(ArtifactoryGenericConfigurator.java:352) at hudson.model.Build$BuildExecution.doRun(Build.java:171) at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:533) at hudson.model.Run.execute(Run.java:1759) at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43) at hudson.model.ResourceController.execute(ResourceController.java:89) at hudson.model.Executor.run(Executor.java:240) Caused by: java.io.IOException: Unable to serialize hudson.FilePath$FileCallableWrapper@2ca3869b at hudson.remoting.UserRequest.serialize(UserRequest.java:169) at hudson.remoting.UserRequest.(UserRequest.java:63) at hudson.remoting.Channel.call(Channel.java:750) at hudson.FilePath.act(FilePath.java:970) ... 9 more Caused by: java.io.NotSerializableException: hudson.model.FreeStyleBuild at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1547) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1508) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) at hudson.remoting.UserRequest._serialize(UserRequest.java:158) at hudson.remoting.UserRequest.serialize(UserRequest.java:167) ... 12 more Collecting metadata...
我做错了什么?
编辑 1:好的,我看到问题是我在 filesDeployerCallable 中传递 AbstractBuild 构建,它不可序列化,但我需要它来做我做的事情。它确实给了我一个警告(抽象是原始类型,应该参数化)。我如何参数化它?它在 hudson.model.abstractModel
要回答问题如何查明文件是否存在于从站,从主站调用workspace.child("relative/path/to/my.file").exists()
应该就足够了。隐藏本地和远程文件之间的差异是 FilePath
存在的原因。
有几种方法可以解决 Jenkins 模型对象不可序列化的问题。
- 在master上保留逻辑,在slave上发送小任务(
Callable
s)。更容易确保这些任务足够简单,它们永远不需要 Jenkins 模型对象。使用hudson.Launcher
和hudson.FilePath
属于这一类。 - 在发送
Callable
到 slave 之前只提取可序列化的信息。例如,如果您只需要一个构建编号,则无需传输整个构建对象。 - 使用对象 proxies 因此只有域对象的远程代理会出现在从站上,并且所有方法调用都将通过通道分派。