public Result run(BuildListener listener) throws Exception { Node node = getCurrentNode(); assert builtOn == null; builtOn = node.getNodeName(); hudsonVersion = Hudson.VERSION; this.listener = listener; launcher = createLauncher(listener); if (!Hudson.getInstance().getNodes().isEmpty()) listener .getLogger() .println( node instanceof Hudson ? Messages.AbstractBuild_BuildingOnMaster() : Messages.AbstractBuild_BuildingRemotely(builtOn)); final Lease lease = decideWorkspace(node, Computer.currentComputer().getWorkspaceList()); try { workspace = lease.path.getRemote(); node.getFileSystemProvisioner().prepareWorkspace(AbstractBuild.this, lease.path, listener); if (project.isCleanWorkspaceRequired()) { listener .getLogger() .println( "Cleaning the workspace because project is configured to clean the workspace before each build."); if (!project.cleanWorkspace()) { listener .getLogger() .println("Workspace cleaning was attempted but SCM blocked the cleaning."); } } checkout(listener); if (!preBuild(listener, project.getProperties())) return Result.FAILURE; Result result = doRun(listener); Computer c = node.toComputer(); if (c == null || c.isOffline()) { // As can be seen in HUDSON-5073, when a build fails because of the slave connectivity // problem, // error message doesn't point users to the slave. So let's do it here. listener.hyperlink( "/computer/" + builtOn + "/log", "Looks like the node went offline during the build. Check the slave log for the details."); // grab the end of the log file. This might not work very well if the slave already // starts reconnecting. Fixing this requires a ring buffer in slave logs. AnnotatedLargeText<Computer> log = c.getLogText(); StringWriter w = new StringWriter(); log.writeHtmlTo(Math.max(0, c.getLogFile().length() - 10240), w); listener.getLogger().print(ExpandableDetailsNote.encodeTo("details", w.toString())); listener.getLogger().println(); } // kill run-away processes that are left // use multiple environment variables so that people can escape this massacre by overriding // an environment // variable for some processes launcher.kill(getCharacteristicEnvVars()); // this is ugly, but for historical reason, if non-null value is returned // it should become the final result. if (result == null) result = getResult(); if (result == null) result = Result.SUCCESS; return result; } finally { lease.release(); this.listener = null; } }