Cannot access file on Jenkins slave with plugin

3.5k views Asked by At

Through my own plugin, I need to know about the existence of a file in the workspace of a Jenkins slave. But the file can't be found whereas it really exists on the 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$1.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...

what am I doing wrong?

Edit 1: Okay, I see the problem is I am passing AbstractBuild build in filesDeployerCallable which is not serializable but I need it for stuff I do. It does give me a warning as to (abstract is raw type and should be parameterized). How Do I parameterize it ? its in the hudson.model.abstractModel

1

There are 1 answers

0
Oliver Gondža On BEST ANSWER

To answer the question How to find out if file exists on a slave, it should be enough to call workspace.child("relative/path/to/my.file").exists() from master. Hiding the difference between local and remote files is the reason FilePath exist.


There are several way to get around Jenkins model objects not being serializable.

  1. Keep the logic on master and send small tasks (Callables) on slave. It is easier to make sure those tasks are simple enough they will never need Jenkins model objects. Using hudson.Launcher and hudson.FilePath falls into this category.
  2. Extract only serializable information before sending Callable to slave. For example if all you need is a build number, there is no need to transfer whole build object.
  3. Use object proxies so only a remote proxy of a domain object will be present on a slave and all method calls will be dispatched over a channel.