From 9b3f48853d481b848f91b4f6fb7d96e87e81b500 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Tue, 23 Sep 2014 17:32:46 +0200 Subject: [PATCH 1/3] [FIXED JENKINS-24825] define hudson.model.AbstractItem#movedTo --- changelog.html | 3 +++ core/src/main/java/hudson/model/AbstractItem.java | 6 ++++++ core/src/main/java/hudson/model/Items.java | 2 +- core/src/main/java/hudson/model/Job.java | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/changelog.html b/changelog.html index d22f6730ed..6c098499d8 100644 --- a/changelog.html +++ b/changelog.html @@ -91,6 +91,9 @@ Upcoming changes
  • umask setting on Debian did not work. (pull 1397) +
  • + handle job move when buildDir is configured to a custom location. + (issue 24825)

    What's new in 1.581 (2014/09/21)

    diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index 115a01e635..6e5ff33d75 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -42,6 +42,7 @@ import hudson.util.AlternativeUiTextProvider; import hudson.util.AlternativeUiTextProvider.Message; import hudson.util.AtomicFileWriter; import hudson.util.IOUtils; +import jenkins.model.DirectlyModifiableTopLevelItemGroup; import jenkins.model.Jenkins; import org.apache.tools.ant.taskdefs.Copy; import org.apache.tools.ant.types.FileSet; @@ -308,6 +309,10 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet } } + public void movedTo(DirectlyModifiableTopLevelItemGroup destination, AbstractItem newItem, File destDir) throws IOException { + newItem.onLoad(destination, name); + } + /** * A pointless function to work around what appears to be a HotSpot problem. See JENKINS-5756 and bug 6933067 * on BugParade for more details. @@ -712,4 +717,5 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet * Replaceable pronoun of that points to a job. Defaults to "Job"/"Project" depending on the context. */ public static final Message PRONOUN = new Message(); + } diff --git a/core/src/main/java/hudson/model/Items.java b/core/src/main/java/hudson/model/Items.java index ca8b54fb77..0358e4471a 100644 --- a/core/src/main/java/hudson/model/Items.java +++ b/core/src/main/java/hudson/model/Items.java @@ -381,7 +381,7 @@ public class Items { FileUtils.moveDirectory(item.getRootDir(), destDir); oldParent.remove(item); I newItem = destination.add(item, name); - newItem.onLoad(destination, name); + item.movedTo(destination, newItem, destDir); ItemListener.fireLocationChange(newItem, oldFullName); return newItem; } diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index e7aebb77d2..b3e05c6888 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -63,6 +63,7 @@ import hudson.widgets.HistoryWidget; import hudson.widgets.HistoryWidget.Adapter; import hudson.widgets.Widget; import jenkins.model.BuildDiscarder; +import jenkins.model.DirectlyModifiableTopLevelItemGroup; import jenkins.model.Jenkins; import jenkins.model.ProjectNamingStrategy; import jenkins.security.HexStringConfidentialKey; @@ -70,6 +71,7 @@ import jenkins.util.io.OnMaster; import net.sf.json.JSONException; import net.sf.json.JSONObject; +import org.apache.commons.io.FileUtils; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; @@ -628,6 +630,18 @@ public abstract class Job, RunT extends Run Date: Wed, 24 Sep 2014 15:30:54 +0200 Subject: [PATCH 2/3] javadoc --- core/src/main/java/hudson/model/AbstractItem.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index 6e5ff33d75..a34fbe0d96 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -309,6 +309,15 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet } } + /** + * Notify this item it's been moved to another location, replaced by newItem (might be the same object, but not guaranteed). + * This method is executed after the item root directory has been moved to it's new location. + *

    + * Derived classes can override this method to add some specific behavior on move, but have to call parent method + * so the item is actually setup within it's new parent. + * + * @see hudson.model.Items#move(AbstractItem, jenkins.model.DirectlyModifiableTopLevelItemGroup) + */ public void movedTo(DirectlyModifiableTopLevelItemGroup destination, AbstractItem newItem, File destDir) throws IOException { newItem.onLoad(destination, name); } From 8975b0e0b5b5c553301c7bc85fd81d080a658b96 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Wed, 24 Sep 2014 16:59:37 +0200 Subject: [PATCH 3/3] test case for JENKINS-24825 --- test/src/test/java/hudson/model/ItemsTest.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/src/test/java/hudson/model/ItemsTest.java b/test/src/test/java/hudson/model/ItemsTest.java index 8e969013ad..566fe380dd 100644 --- a/test/src/test/java/hudson/model/ItemsTest.java +++ b/test/src/test/java/hudson/model/ItemsTest.java @@ -24,10 +24,14 @@ package hudson.model; +import java.io.File; import java.util.Arrays; + +import hudson.Util; import org.junit.Test; import static org.junit.Assert.*; import org.junit.Rule; +import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockFolder; @@ -56,4 +60,17 @@ public class ItemsTest { assertEquals(Arrays.asList(sub2a, sub2ap, sub2alpha, sub2b, sub2bp, sub2BRAVO, sub2c, sub2cp, sub2charlie), Items.getAllItems(sub2, Item.class)); } + @Issue("JENKINS-24825") + @Test public void moveItem() throws Exception { + File tmp = Util.createTempDir(); + r.jenkins.setRawBuildsDir(tmp.getAbsolutePath()+"/${ITEM_FULL_NAME}"); + MockFolder foo = r.createFolder("foo"); + MockFolder bar = r.createFolder("bar"); + FreeStyleProject test = foo.createProject(FreeStyleProject.class, "test"); + test.scheduleBuild2(0).get(); + Items.move(test, bar); + assertFalse(new File(tmp, "foo/test/1").exists()); + assertTrue(new File(tmp, "bar/test/1").exists()); + } + }