From a7a518e27f4b44fc97ede31d5a82c6112762f7fc Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Mon, 29 Mar 2021 13:13:11 -0400 Subject: [PATCH 1/2] Using a plugin to implement RealJenkinsRuleInit rather than a Groovy init script --- RealJenkinsRuleInit/pom.xml | 61 ++++++++++++++++++ .../hudson/test/RealJenkinsRuleInit.java | 24 ++++++- .../jvnet/hudson/test/RealJenkinsRule.java | 15 ++--- .../jvnet/hudson/test/RealJenkinsRuleInit.jpi | Bin 0 -> 5920 bytes 4 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 RealJenkinsRuleInit/pom.xml rename src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.groovy => RealJenkinsRuleInit/src/main/java/org/jvnet/hudson/test/RealJenkinsRuleInit.java (60%) create mode 100644 src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.jpi diff --git a/RealJenkinsRuleInit/pom.xml b/RealJenkinsRuleInit/pom.xml new file mode 100644 index 000000000..928697c0c --- /dev/null +++ b/RealJenkinsRuleInit/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + 4.17 + + + io.jenkins.plugins + RealJenkinsRuleInit + 0-SNAPSHOT + hpi + + 2.222.1 + 8 + + RealJenkinsRule initialization wrapper + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.2 + + + copy-installed + install + + copy + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + ${project.packaging} + ${project.basedir}/../src/main/resources/org/jvnet/hudson/test + RealJenkinsRuleInit.jpi + + + + + + + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.groovy b/RealJenkinsRuleInit/src/main/java/org/jvnet/hudson/test/RealJenkinsRuleInit.java similarity index 60% rename from src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.groovy rename to RealJenkinsRuleInit/src/main/java/org/jvnet/hudson/test/RealJenkinsRuleInit.java index cc583e196..a0ffd80bb 100644 --- a/src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.groovy +++ b/RealJenkinsRuleInit/src/main/java/org/jvnet/hudson/test/RealJenkinsRuleInit.java @@ -22,6 +22,24 @@ * THE SOFTWARE. */ -import jenkins.model.Jenkins -URL[] urls = [new URL(System.getProperty('RealJenkinsRule.location'))] -new URLClassLoader(urls, ClassLoader.systemClassLoader.parent).loadClass('org.jvnet.hudson.test.RealJenkinsRule$Init2').getMethod('run', Object).invoke(null, Jenkins.instance) +package org.jvnet.hudson.test; + +import hudson.Plugin; +import java.net.URL; +import java.net.URLClassLoader; +import jenkins.model.Jenkins; + +public class RealJenkinsRuleInit extends Plugin { + + @SuppressWarnings("deprecation") // @Initializer just gets run too late, even with before = InitMilestone.PLUGINS_PREPARED + public RealJenkinsRuleInit() {} + + @Override + public void start() throws Exception { + new URLClassLoader(new URL[] {new URL(System.getProperty("RealJenkinsRule.location"))}, ClassLoader.getSystemClassLoader().getParent()). + loadClass("org.jvnet.hudson.test.RealJenkinsRule$Init2"). + getMethod("run", Object.class). + invoke(null, Jenkins.get()); + } + +} diff --git a/src/main/java/org/jvnet/hudson/test/RealJenkinsRule.java b/src/main/java/org/jvnet/hudson/test/RealJenkinsRule.java index adb10e508..75ce4206c 100644 --- a/src/main/java/org/jvnet/hudson/test/RealJenkinsRule.java +++ b/src/main/java/org/jvnet/hudson/test/RealJenkinsRule.java @@ -25,9 +25,7 @@ package org.jvnet.hudson.test; import hudson.ExtensionList; -import hudson.model.DownloadService; import hudson.model.UnprotectedRootAction; -import hudson.model.UpdateSite; import hudson.security.ACL; import hudson.security.ACLContext; import hudson.security.csrf.CrumbExclusion; @@ -193,12 +191,10 @@ public RealJenkinsRule withTimeout(int timeout) { System.out.println("=== Starting " + description); try { home = tmp.allocate(); - File initGroovyD = new File(home, "init.groovy.d"); - initGroovyD.mkdir(); - FileUtils.copyURLToFile(RealJenkinsRule.class.getResource("RealJenkinsRuleInit.groovy"), new File(initGroovyD, "RealJenkinsRuleInit.groovy")); port = new Random().nextInt(16384) + 49152; // https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic,_private_or_ephemeral_ports File plugins = new File(home, "plugins"); plugins.mkdir(); + FileUtils.copyURLToFile(RealJenkinsRule.class.getResource("RealJenkinsRuleInit.jpi"), new File(plugins, "RealJenkinsRuleInit.jpi")); // Adapted from UnitTestSupportingPluginManager & JenkinsRule.recipeLoadCurrentPlugin: Set snapshotPlugins = new TreeSet<>(); Enumeration indexJellies = RealJenkinsRule.class.getClassLoader().getResources("index.jelly"); @@ -471,7 +467,8 @@ private Init2() {} public static final class Endpoint implements UnprotectedRootAction { @SuppressWarnings("deprecation") public static void register() throws Exception { - Jenkins.get().getActions().add(new Endpoint()); + Jenkins j = Jenkins.get(); + j.getActions().add(new Endpoint()); CrumbExclusion.all().add(new CrumbExclusion() { @Override public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { if (request.getPathInfo().startsWith("/RealJenkinsRule/")) { @@ -481,9 +478,7 @@ public static void register() throws Exception { return false; } }); - Jenkins.get().setNoUsageStatistics(true); - DownloadService.neverUpdate = true; - UpdateSite.neverUpdate = true; + JenkinsRule._configureUpdateCenter(j); System.err.println("RealJenkinsRule ready"); Timer.get().scheduleAtFixedRate(JenkinsRule::dumpThreads, 2, 2, TimeUnit.MINUTES); } @@ -532,7 +527,7 @@ public static final class CustomJenkinsRule extends JenkinsRule implements AutoC public CustomJenkinsRule() throws Exception { this.jenkins = Jenkins.get(); localPort = Integer.getInteger("RealJenkinsRule.port"); - // Stuff picked out of before(), configureUpdateCenter(): + jenkins.setNoUsageStatistics(true); // cannot use JenkinsRule._configureJenkinsForTest earlier because it tries to save config before loaded JenkinsLocationConfiguration.get().setUrl(getURL().toString()); testDescription = Description.createSuiteDescription(System.getProperty("RealJenkinsRule.description")); env = new TestEnvironment(this.testDescription); diff --git a/src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.jpi b/src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.jpi new file mode 100644 index 0000000000000000000000000000000000000000..d0dcc62e855ecc70fec283a83d0d70e19446a954 GIT binary patch literal 5920 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 Date: Mon, 29 Mar 2021 14:11:00 -0400 Subject: [PATCH 2/2] Moving minimum Jenkins version to 2.204 --- RealJenkinsRuleInit/pom.xml | 4 +++- pom.xml | 2 +- .../jvnet/hudson/test/RealJenkinsRuleInit.jpi | Bin 5920 -> 5856 bytes 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/RealJenkinsRuleInit/pom.xml b/RealJenkinsRuleInit/pom.xml index 928697c0c..159ac18e8 100644 --- a/RealJenkinsRuleInit/pom.xml +++ b/RealJenkinsRuleInit/pom.xml @@ -12,8 +12,10 @@ 0-SNAPSHOT hpi - 2.222.1 + 2.204 8 + true + true RealJenkinsRule initialization wrapper diff --git a/pom.xml b/pom.xml index fa21e947f..5caf18ab4 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,7 @@ THE SOFTWARE. org.jenkins-ci.main jenkins-war - 2.138.4 + 2.204 executable-war diff --git a/src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.jpi b/src/main/resources/org/jvnet/hudson/test/RealJenkinsRuleInit.jpi index d0dcc62e855ecc70fec283a83d0d70e19446a954..50947410a7e8210eadfae6b71dec8ab46fb15670 100644 GIT binary patch delta 4532 zcmZWt2Q(Z^*G6=*+Aa}2T8Q3-wQ3MuuzF4O-un_IMA@)1aV z4GkG5K?`%7=OJt*_zBr+peZQm3CC(H-2cX6J(tt(Nh6Y4o7xvouVmc(HJiG4dm2lO z#M_@~$b8F5etwYCG1HBr0vKj4q9+a*c=p5B+l_VA`Fmm)^Wx(y?^@ zqqD;uYr9&xAGdKvV)bu3;PMrf@@rLj8Bn3L7P>NHh=H}@paBkOwh73~BtC5KjuK4K z6yW_+k)dq+QRPo=jU8+6mVipnQNiePx&oO9nT2h}4fg+y6Jj5o34`ASL5A`CUQ~lI zu+Rbg_i?)_)3FP^4`v?`Lj4gJ%z&=9w{0lYjHPi_bM^umW7z+)=jC}qZDs7c9@!+n zeLL$261}GBywK1}!_XhZuOsZ);=ynCcN&p6$T7EUl(?1gCj7)VKw|08scqAL)MvNr z`SWdblkfzqAO_Q=ocT;=!O)KpNfk{gw@^w>NmnR&b}CLJ{UfySesr`xSRkdL98}3@ z7?%MbO2lI=*-DBtg^|ssrtP}EUK9FeYGWkn=q13i)=YH$4PB8$hf5b1>48<%rrL!@ zCOYae`{{8ral)75m2(~Mb48{helhOMC-2#-H6nF*V}BS>zn+&4CO}A1y@& zm6;_P%WlNEH{U0w|JCve0INXiH9oI)_8p%7Vc}u4EF>?7qU^;Xel<6!q1%cNQL&wV zOS^u2nVz9vx)+x;)}jfYMtv;~-*DW@?rXB7QXduP|H!Fp+|Vk0gMX^WVp@B0iK-LC zv_04-jBCg=tV_{iyc!bw#W){&G)Io!e!@83AhV*X=LdfGdKgQV3+5#;J>ri1UYyq+ zzwP!~#$|TE*C+{4f7wgvILP^P>%5cGLd$36@yw*|FNNX?>tgY@i;&&D(ViIpY=5S- zk#3hOugAnxESAKxV-o_IF63g5kDp%9S}P|kstPBz>UC+mYs`*od_l%zzf^x5CsL^3 z-fcgy{J4-==%8>{L>|^9Ts3HPsb5^M!bu=%ly8&vo5OQtdw%lI-J(gP(|NMbT~97e z%Qsa|fOTcpSwiy!lHiI4>joOePrea!6$|i}+}v`2d&&pM2PPy?uLbq&i6xqd|JK-S z3G;+vG$W$cvr%0yN)LBp+@))yY})N9>_0@h*PnD@y=?XktAWYNHV4lg#mYID`Ⓢ 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 Ii0onIUs4HjJpcdz delta 4593 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 e|J+;PH2_@q$NvGYQeT5=@Bw