/******************************************************************************* * * Copyright (c) 2004-2009 Oracle Corporation. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * Kohsuke Kawaguchi * * *******************************************************************************/ package hudson.matrix; import hudson.FilePath; import hudson.slaves.WorkspaceList; import hudson.slaves.WorkspaceList.Lease; import static hudson.matrix.MatrixConfiguration.useShortWorkspaceName; import hudson.model.Build; import hudson.model.Node; import org.kohsuke.stapler.Ancestor; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import java.io.File; import java.io.IOException; import java.util.Calendar; import java.util.List; import java.util.Map; /** * Execution of {@link MatrixConfiguration}. * * @author Kohsuke Kawaguchi */ public class MatrixRun extends Build<MatrixConfiguration, MatrixRun> { public MatrixRun(MatrixConfiguration job) throws IOException { super(job); } public MatrixRun(MatrixConfiguration job, Calendar timestamp) { super(job, timestamp); } public MatrixRun(MatrixConfiguration project, File buildDir) throws IOException { super(project, buildDir); } @Override public String getUpUrl() { StaplerRequest req = Stapler.getCurrentRequest(); if (req != null) { List<Ancestor> ancs = req.getAncestors(); for (int i = 1; i < ancs.size(); i++) { if (ancs.get(i).getObject() == this) { Object parentObj = ancs.get(i - 1).getObject(); if (parentObj instanceof MatrixBuild || parentObj instanceof MatrixConfiguration) { return ancs.get(i - 1).getUrl() + '/'; } } } } return super.getDisplayName(); } /** * Gets the {@link MatrixBuild} that has the same build number. * * @return null if no such build exists, which happens when the module build * is manually triggered. */ public MatrixBuild getParentBuild() { return getParent().getParent().getBuildByNumber(getNumber()); } @Override public void checkPermission(hudson.security.Permission p) { MatrixBuild parentBuild = getParentBuild(); if (parentBuild != null) { parentBuild.checkPermission(p); } } ; @Override public String getDisplayName() { StaplerRequest req = Stapler.getCurrentRequest(); if (req != null) { List<Ancestor> ancs = req.getAncestors(); for (int i = 1; i < ancs.size(); i++) { if (ancs.get(i).getObject() == this) { if (ancs.get(i - 1).getObject() instanceof MatrixBuild) { return getParent().getCombination().toCompactString(getParent().getParent().getAxes()); } } } } return super.getDisplayName(); } /** * @since 2.1.0 */ @Override protected void customizeBuildVariables(final Map<String, String> vars) { AxisList axes = getParent().getParent().getAxes(); for (Map.Entry<String, String> e : getParent().getCombination().entrySet()) { Axis a = axes.find(e.getKey()); if (a != null) { a.addBuildVariable(e.getValue(), vars); } else { vars.put(e.getKey(), e.getValue()); } } } /** * If the parent {@link MatrixBuild} is kept, keep this record too. */ @Override public String getWhyKeepLog() { MatrixBuild pb = getParentBuild(); if (pb != null && pb.getWhyKeepLog() != null) { return Messages.MatrixRun_KeptBecauseOfParent(pb); } return super.getWhyKeepLog(); } @Override public MatrixConfiguration getParent() {// don't know why, but javac wants this return super.getParent(); } @Override public void run() { run(new RunnerImpl()); } protected class RunnerImpl extends Build<MatrixConfiguration, MatrixRun>.RunnerImpl { @Override protected Lease decideWorkspace(Node n, WorkspaceList wsl) throws InterruptedException, IOException { // Map current combination to a directory subtree, e.g. 'axis1=a,axis2=b' to 'axis1/a/axis2/b'. String subtree; if (useShortWorkspaceName) { subtree = getParent().getDigestName(); } else { subtree = getParent().getCombination().toString('/', '/', true); } String customWorkspace = getParent().getParent().getCustomWorkspace(); if (customWorkspace != null) { // Use custom workspace as defined in the matrix project settings. FilePath ws = n.getRootPath().child(getEnvironment(listener).expand(customWorkspace)); // We allow custom workspaces to be used concurrently between jobs. return Lease.createDummyLease(ws.child(subtree)); } else { // Use default workspace as assigned by Hudson. Node node = getBuiltOn(); FilePath ws = node.getWorkspaceFor(getParent().getParent()); // Allocate unique workspace (not to be shared between jobs and runs). return wsl.allocate(ws.child(subtree)); } } } }