diff --git a/pom.xml b/pom.xml index a563db09..5f04fbd4 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,7 @@ org.jenkins-ci.plugins plugin - 3.25 + 3.28 org.jenkins-ci.plugins.workflow diff --git a/src/main/java/org/jenkinsci/plugins/workflow/log/FileLogStorage.java b/src/main/java/org/jenkinsci/plugins/workflow/log/FileLogStorage.java index d19c7f34..5432a772 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/log/FileLogStorage.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/log/FileLogStorage.java @@ -322,4 +322,9 @@ private void maybeFlush() { } } + @Deprecated + @Override public File getLogFile(FlowExecutionOwner.Executable build, boolean complete) { + return log; + } + } diff --git a/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java b/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java index 9035d3b3..87e5ed50 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java @@ -24,13 +24,19 @@ package org.jenkinsci.plugins.workflow.log; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.ExtensionList; import hudson.console.AnnotatedLargeText; import hudson.console.ConsoleAnnotationOutputStream; import hudson.model.BuildListener; +import hudson.model.Run; import hudson.model.TaskListener; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.annotation.Nonnull; import org.jenkinsci.plugins.workflow.actions.LogAction; import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner; @@ -108,6 +114,44 @@ public interface LogStorage { */ @Nonnull AnnotatedLargeText stepLog(@Nonnull FlowNode node, boolean complete); + /** + * Provide a file containing the log text. + * The default implementation creates a temporary file based on the current contents of {@link #overallLog}. + * @param build as in {@link #overallLog} + * @param complete as in {@link #overallLog} + * @return a possibly temporary file + * @deprecated Only used for compatibility with {@link Run#getLogFile}. + */ + @SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "silly rule") + @Deprecated + default @Nonnull File getLogFile(@Nonnull FlowExecutionOwner.Executable build, boolean complete) { + try { + AnnotatedLargeText logText = overallLog(build, complete); + FlowExecutionOwner owner = build.asFlowExecutionOwner(); + File f = File.createTempFile("deprecated", ".log", owner != null ? owner.getRootDir() : null); + f.deleteOnExit(); + try (OutputStream os = new FileOutputStream(f)) { + // Similar to Run#writeWholeLogTo but terminates even if !complete: + long pos = 0; + while (true) { + long pos2 = logText.writeRawLogTo(pos, os); + if (pos2 <= pos) { + break; + } + pos = pos2; + } + } + return f; + } catch (Exception x) { + Logger.getLogger(LogStorage.class.getName()).log(Level.WARNING, null, x); + if (build instanceof Run) { + return new File(((Run) build).getRootDir(), "log"); + } else { + return new File("broken.log"); // not much we can do + } + } + } + /** * Gets the available log storage method for a given build. * @param b a build about to start diff --git a/src/test/java/org/jenkinsci/plugins/workflow/log/LogStorageTestBase.java b/src/test/java/org/jenkinsci/plugins/workflow/log/LogStorageTestBase.java index c69d215b..bcbe068d 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/log/LogStorageTestBase.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/log/LogStorageTestBase.java @@ -38,10 +38,14 @@ import java.util.concurrent.Callable; import java.util.function.BiFunction; import jenkins.security.MasterToSlaveCallable; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.output.NullOutputStream; import org.apache.commons.io.output.NullWriter; import org.apache.commons.io.output.WriterOutputStream; +import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.graph.FlowNode; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; import static org.junit.Assert.*; import org.junit.Before; import org.junit.ClassRule; @@ -221,6 +225,26 @@ private static final class RemotePrint extends MasterToSlaveCallable