Skip to content
Permalink
Browse files
fixes [JENKINS-11374] - Add deletion option on "list of Shelved Projects
  • Loading branch information
christiangalsterer committed Mar 23, 2014
1 parent 2df406a commit aa537fc52f9589f73af35c875a7b4615a95cdc01
@@ -0,0 +1,75 @@
package org.jvnet.hudson.plugins.shelveproject;

import hudson.model.Hudson;
import hudson.model.Queue;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.File;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DeleteProjectExecutable
implements Queue.Executable
{
private final static Logger LOGGER = Logger.getLogger( DeleteProjectExecutable.class.getName() );

private final String[] shelvedProjectArchiveNames;

private final Queue.Task parentTask;

public DeleteProjectExecutable(Queue.Task parentTask, String[] shelvedProjectArchiveNames)
{
this.parentTask = parentTask;
this.shelvedProjectArchiveNames = shelvedProjectArchiveNames;
}

public Queue.Task getParent()
{
return parentTask;
}

public void run()
{
for (String shelvedProjectArchiveName : shelvedProjectArchiveNames)
{
final File shelvedProjectArchive = getArchiveFile(shelvedProjectArchiveName);
LOGGER.info( "Deleting project [" + shelvedProjectArchiveName + "]." );
try
{
shelvedProjectArchive.delete();
}
catch ( Exception e )
{
LOGGER.log( Level.SEVERE, "Could not delete project archive [" + shelvedProjectArchiveName + "].", e );
}
}
}

private File getArchiveFile(String shelvedProjectArchiveName) {
// JENKINS-8759 - The archive name comes from the html form, so take a bit extra care for security reasons by
// only accessing the archive if it exists in the directory of shevled projects.
File shelvedProjectsDirectory = new File( Hudson.getInstance().getRootDir(), "shelvedProjects" );
Collection<File> files = FileUtils.listFiles(shelvedProjectsDirectory, null, false);
for (File file : files)
{
if (StringUtils.equals(file.getName(), shelvedProjectArchiveName))
{
return file;
}
}
return null; // Project was already unshelved?
}

public long getEstimatedDuration()
{
return -1; // impossible to estimate duration
}

@Override
public String toString()
{
return "Deleting Project";
}
}
@@ -0,0 +1,124 @@
package org.jvnet.hudson.plugins.shelveproject;

import hudson.model.Label;
import hudson.model.Node;
import hudson.model.Queue;
import hudson.model.ResourceList;
import hudson.model.queue.CauseOfBlockage;
import hudson.model.queue.SubTask;
import hudson.security.ACL;
import org.acegisecurity.Authentication;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

public class DeleteProjectTask
implements Queue.FlyweightTask, Queue.TransientTask
{
private final String[] shelvedProjectArchiveNames;

public DeleteProjectTask(String[] shelvedProjectArchiveNames)
{
this.shelvedProjectArchiveNames = shelvedProjectArchiveNames;
}

public Label getAssignedLabel()
{
return null;
}

public Node getLastBuiltOn()
{
return null;
}

public boolean isBuildBlocked()
{
return false;
}

public String getWhyBlocked()
{
return null;
}

public CauseOfBlockage getCauseOfBlockage() {
return null;
}

public String getName()
{
return "Deleting Project";
}

public String getFullDisplayName()
{
return getName();
}

public long getEstimatedDuration()
{
return -1;
}

public Queue.Executable createExecutable()
throws IOException
{
return new DeleteProjectExecutable(this, shelvedProjectArchiveNames);
}

public Queue.Task getOwnerTask()
{
return this;
}

public Object getSameNodeConstraint()
{
return null;
}

public void checkAbortPermission()
{
}

public boolean hasAbortPermission()
{
return false;
}

public String getUrl()
{
return null;
}

public boolean isConcurrentBuild()
{
return false;
}

public Collection<? extends SubTask> getSubTasks()
{
final List<SubTask> subTasks = new LinkedList<SubTask>();
subTasks.add(this);
return subTasks;
}

public ResourceList getResourceList()
{
return new ResourceList();
}

public String getDisplayName()
{
return getName();
}

@Nonnull
public Authentication getDefaultAuthentication() {
return ACL.SYSTEM;
}

}
@@ -104,10 +104,18 @@ private ShelvedProject getShelvedProjectFromArchive( File archive )
}

@SuppressWarnings({"UnusedDeclaration"})
public HttpResponse doUnshelveProject( StaplerRequest request,
public HttpResponse doManageShelvedProject( StaplerRequest request,
StaplerResponse response )
throws IOException, ServletException
{
if(request.hasParameter("unshelve"))
return unshelveProject(request);
else if (request.hasParameter("delete"))
return deleteProject(request);
return createRedirectToShelvedProjectsPage();
}

private HttpResponse unshelveProject(StaplerRequest request) {
Hudson.getInstance().checkPermission( Permission.CREATE );

final String[] archives = request.getParameterValues("archives");
@@ -123,6 +131,22 @@ public HttpResponse doUnshelveProject( StaplerRequest request,
return createRedirectToMainPage();
}

private HttpResponse deleteProject(StaplerRequest request) {
Hudson.getInstance().checkPermission( Permission.DELETE );

final String[] archives = request.getParameterValues("archives");
if (archives == null)
{
return createRedirectToShelvedProjectsPage();
}

LOGGER.info("Deleting archived projects.");
// Deleting the project could take some time, so add it as a task
Hudson.getInstance().getQueue().schedule( new DeleteProjectTask(archives), 0 );

return createRedirectToShelvedProjectsPage();
}

public String formatDate( long timestamp )
{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "EEE, d MMM yyyy HH:mm:ss Z" );
@@ -11,7 +11,7 @@
<j:set var="shelvedProjectsList" value="${it.shelvedProjects}"/>
<j:choose>
<j:when test="${!shelvedProjectsList.isEmpty()}">
<form method="post" action="unshelveProject">
<form method="post" action="manageShelvedProject">
<ol>
<j:forEach var="shelvedProject" items="${shelvedProjectsList}">
<input type="checkbox" name="archives" value="${shelvedProject.archive.name}"/>
@@ -20,7 +20,8 @@
</ol>

<div align="right">
<input type="submit" value="Unshelve Project" class="submit-button"/>
<input type="submit" name="unshelve" value="Unshelve Project" class="submit-button"/>
<input type="submit" name="delete" value="Delete Project" class="submit-button"/>
</div>
</form>
</j:when>
@@ -0,0 +1,69 @@

package org.jvnet.hudson.plugins.shelveproject;

import hudson.model.FreeStyleBuild;
import hudson.model.FreeStyleProject;
import hudson.model.Hudson;
import hudson.model.Queue.Task;
import hudson.tasks.Shell;
import org.jvnet.hudson.test.HudsonTestCase;

import java.io.File;
import java.util.ArrayList;

/**
* @author christian.galsterer
*/
public class DeleteProjectExecutableTest extends HudsonTestCase {
private Task parentTask;


public void testProjectZipIsDeleted() throws Exception {

String projectname = "ProjectWithWorkspace";
String file;
ArrayList<String> files = new ArrayList<String>();

FreeStyleProject project = createFreeStyleProject(projectname);
project.getBuildersList().add(new Shell("echo hello"));

FreeStyleBuild b = project.scheduleBuild2(0).get();

assertTrue("Workspace should exist by now",
b.getWorkspace().exists());

File shelvedProjectsDir = new File(Hudson.getInstance().getRootDir(), "shelvedProjects");
shelvedProjectsDir.mkdirs();

ShelveProjectExecutable a = new ShelveProjectExecutable(parentTask, project);
a.run();

// Read through target directory and find that the zip has been created.
File[] listOfFiles = shelvedProjectsDir.listFiles();
for (File listOfFile : listOfFiles) {
if (listOfFile.isFile()) {
file = listOfFile.getName();
files.add(file);
if (file.startsWith(projectname) && (file.endsWith(".zip"))) {
assertTrue("Found project .zip file in shelvedProjects", true);
} else {
fail("Did not find project .zip file in shelvedProjects");
}
}
}

DeleteProjectExecutable deleteProjectExecutable = new DeleteProjectExecutable(parentTask, files.toArray(new String[files.size()]));
deleteProjectExecutable.run();

// Read through target directory and find that the zip has been deleted.
listOfFiles = shelvedProjectsDir.listFiles();
for (File listOfFile : listOfFiles) {
if (listOfFile.isFile()) {
file = listOfFile.getName();
if (files.contains(file)) {
fail("Found project .zip file in shelvedProjects");
}
}
}
}
}

0 comments on commit aa537fc

Please sign in to comment.