From eeb597c7e0bd31b0c40287e5ddf2d9cf4f3c1db0 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 9 Nov 2018 13:00:36 -0500 Subject: [PATCH 1/5] [JENKINS-54128] Define an SPI in LogStorage to satisfy WorkflowRun.getLogFile. --- pom.xml | 2 +- .../plugins/workflow/log/FileLogStorage.java | 5 +++ .../plugins/workflow/log/LogStorage.java | 38 +++++++++++++++++++ .../workflow/log/LogStorageTestBase.java | 24 ++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) 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..ed7b4a52 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java @@ -28,9 +28,12 @@ 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 javax.annotation.Nonnull; import org.jenkinsci.plugins.workflow.actions.LogAction; import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner; @@ -108,6 +111,41 @@ 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}. + */ + @Deprecated + default @Nonnull File getLogFile(@Nonnull FlowExecutionOwner.Executable build, boolean complete) { + try { + AnnotatedLargeText logText = overallLog(build, complete); + File f = File.createTempFile("deprecated", ".log", build instanceof Run ? ((Run) build).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) { + 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 Date: Fri, 9 Nov 2018 13:10:27 -0500 Subject: [PATCH 2/5] Javadoc --- .../java/org/jenkinsci/plugins/workflow/log/LogStorage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 ed7b4a52..ae025144 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java @@ -114,8 +114,8 @@ public interface LogStorage { /** * 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 + * @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}. */ From 4f0bc3b78ff6431528bc2d93c0f82165b4da2753 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 9 Nov 2018 13:25:36 -0500 Subject: [PATCH 3/5] FindBugs --- .../java/org/jenkinsci/plugins/workflow/log/LogStorage.java | 2 ++ 1 file changed, 2 insertions(+) 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 ae025144..3c1b169d 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java @@ -24,6 +24,7 @@ package org.jenkinsci.plugins.workflow.log; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.ExtensionList; import hudson.console.AnnotatedLargeText; import hudson.console.ConsoleAnnotationOutputStream; @@ -119,6 +120,7 @@ public interface LogStorage { * @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 { From 5f9ac65fd5f22cbc8f611fb0811380fe2f620f35 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 9 Nov 2018 13:30:26 -0500 Subject: [PATCH 4/5] Better to use FlowExecutionOwner.getRootDir. --- .../java/org/jenkinsci/plugins/workflow/log/LogStorage.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 3c1b169d..1415f239 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java @@ -125,7 +125,8 @@ public interface LogStorage { default @Nonnull File getLogFile(@Nonnull FlowExecutionOwner.Executable build, boolean complete) { try { AnnotatedLargeText logText = overallLog(build, complete); - File f = File.createTempFile("deprecated", ".log", build instanceof Run ? ((Run) build).getRootDir() : null); + 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: From de46235bb590e8b018979a0b7870c4757b04bc8f Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Fri, 9 Nov 2018 13:50:20 -0500 Subject: [PATCH 5/5] Adding an exception log. --- .../java/org/jenkinsci/plugins/workflow/log/LogStorage.java | 3 +++ 1 file changed, 3 insertions(+) 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 1415f239..87e5ed50 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/log/LogStorage.java @@ -35,6 +35,8 @@ 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; @@ -141,6 +143,7 @@ public interface LogStorage { } 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 {