Skip to content

Commit

Permalink
[JENKINS-26339] SimpleBuildWrapper support.
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed Jan 15, 2015
1 parent fd78c9f commit bcae981
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 66 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.532</version>
<version>1.598-SNAPSHOT</version> <!-- TODO SimpleBuildWrapper-JENKINS-24673 -->
</parent>

<artifactId>config-file-provider</artifactId>
Expand Down
Expand Up @@ -14,7 +14,6 @@
import hudson.tasks.Builder;

import java.io.IOException;
import java.io.PrintStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -55,7 +54,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen
throw new IllegalStateException("the workspace does not yet exist, can't provision config files - maybe slave is offline?");
}

final Map<ManagedFile, FilePath> file2Path = ManagedFileUtil.provisionConfigFiles(managedFiles, build, listener);
final Map<ManagedFile, FilePath> file2Path = ManagedFileUtil.provisionConfigFiles(managedFiles, build, build.getWorkspace(), listener);
// Temporarily attach info about the files to be deleted to the build - this action gets removed from the build again by 'org.jenkinsci.plugins.configfiles.common.CleanTempFilesRunListener'
build.addAction(new CleanTempFilesAction(file2Path));

Expand Down
Expand Up @@ -23,32 +23,29 @@ of this software and associated documentation files (the "Software"), to deal
*/
package org.jenkinsci.plugins.configfiles.buildwrapper;

import hudson.EnvVars;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.tasks.BuildWrapper;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.tasks.BuildWrapperDescriptor;

import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import jenkins.tasks.SimpleBuildWrapper;

import org.apache.commons.lang.StringUtils;
import org.jenkinsci.lib.configprovider.ConfigProvider;
import org.jenkinsci.lib.configprovider.model.Config;
import org.jenkinsci.plugins.configfiles.common.CleanTempFilesAction;
import org.kohsuke.stapler.DataBoundConstructor;

public class ConfigFileBuildWrapper extends BuildWrapper {
public class ConfigFileBuildWrapper extends SimpleBuildWrapper {

private List<ManagedFile> managedFiles = new ArrayList<ManagedFile>();

Expand All @@ -57,22 +54,22 @@ public ConfigFileBuildWrapper(List<ManagedFile> managedFiles) {
this.managedFiles = managedFiles;
}

@Override
public Environment setUp(@SuppressWarnings("rawtypes") AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {

final PrintStream logger = listener.getLogger();

if (build.getWorkspace() == null) {
throw new IllegalStateException("the workspace does not yet exist, can't provision config files - maybe slave is offline?");
@Override public void setUp(Context context, Run<?,?> build, FilePath workspace, Launcher launcher, TaskListener listener, EnvVars initialEnvironment) throws IOException, InterruptedException {
final Map<ManagedFile, FilePath> file2Path = ManagedFileUtil.provisionConfigFiles(managedFiles, build, workspace, listener);
context.env = new EnvVars();
List<String> tempFiles = new ArrayList<String>();
for (Map.Entry<ManagedFile, FilePath> entry : file2Path.entrySet()) {
ManagedFile mf = entry.getKey();
FilePath fp = entry.getValue();
if (!StringUtils.isBlank(mf.variable)) {
context.env.put(mf.variable, fp.getRemote());
}
boolean noTargetGiven = StringUtils.isBlank(entry.getKey().targetLocation);
if (noTargetGiven) {
tempFiles.add(entry.getValue().getRemote());
}
}

final Map<ManagedFile, FilePath> file2Path = ManagedFileUtil.provisionConfigFiles(managedFiles, build, listener);
// JENKINS-17555 this special env is required, as MavenModuleSetBuild only takes Environments from BuildWrapper into account, but not those from Actions registered by them.
final ManagedFilesEnvironment env = new ManagedFilesEnvironment(file2Path);
// Temporarily attach info about the files to be deleted to the build - this action gets removed from the build again by 'org.jenkinsci.plugins.configfiles.common.CleanTempFilesRunListener'
build.addAction(new CleanTempFilesAction(file2Path));

return env;
context.disposer = new TempFileCleaner(tempFiles);
}

public List<ManagedFile> getManagedFiles() {
Expand Down Expand Up @@ -102,42 +99,23 @@ public Collection<Config> getConfigFiles() {

}

/**
* fix for JENKINS-17555
*/
public class ManagedFilesEnvironment extends Environment {
private final Map<ManagedFile, FilePath> file2Path;
private static class TempFileCleaner extends Disposer {

public ManagedFilesEnvironment(Map<ManagedFile, FilePath> file2Path) {
this.file2Path = file2Path == null ? Collections.<ManagedFile, FilePath> emptyMap() : file2Path;
}
private static final long serialVersionUID = 1;

@Override
public void buildEnvVars(Map<String, String> env) {
for (Map.Entry<ManagedFile, FilePath> entry : file2Path.entrySet()) {
ManagedFile mf = entry.getKey();
FilePath fp = entry.getValue();
if (!StringUtils.isBlank(mf.variable)) {
env.put(mf.variable, fp.getRemote());
}
}
private final List<String> tempFiles;

TempFileCleaner(List<String> tempFiles) {
this.tempFiles = tempFiles;
}

/**
* Provides access to the files which have to be removed after the build
*
* @return a list of paths to the temp files (remotes)
*/
List<String> getTempFiles() {
List<String> tempFiles = new ArrayList<String>();
for (Entry<ManagedFile, FilePath> entry : file2Path.entrySet()) {
boolean noTargetGiven = StringUtils.isBlank(entry.getKey().targetLocation);
if (noTargetGiven) {
tempFiles.add(entry.getValue().getRemote());
}
@Override public void tearDown(Run<?,?> build, FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException {
listener.getLogger().println("Deleting " + tempFiles.size() + " temporary files");
for (String tempFile : tempFiles) {
new FilePath(workspace, tempFile).delete();
}
return tempFiles;
}

}

}
Expand Up @@ -24,9 +24,7 @@ of this software and associated documentation files (the "Software"), to deal
package org.jenkinsci.plugins.configfiles.buildwrapper;

import hudson.FilePath;
import hudson.model.BuildListener;
import hudson.model.AbstractBuild;
import hudson.remoting.Callable;
import hudson.remoting.VirtualChannel;

import java.io.ByteArrayInputStream;
Expand All @@ -45,14 +43,17 @@ of this software and associated documentation files (the "Software"), to deal
import org.jenkinsci.plugins.tokenmacro.TokenMacro;

import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials;
import hudson.model.Run;
import hudson.model.TaskListener;
import jenkins.security.MasterToSlaveCallable;

public class ManagedFileUtil {

/**
* creates a tmp file on the given channel
* Seems to be like {@link FilePath#createTempFile}, but passing the 2-arg form to File to use {@code ${java.io.tmpdir}}.
*/
public static FilePath createTempFile(VirtualChannel channel) throws IOException, InterruptedException {
return channel.call(new Callable<FilePath, IOException>() {
return channel.call(new MasterToSlaveCallable<FilePath, IOException>() {
public FilePath call() throws IOException {
final File tmpTarget = File.createTempFile("config", "tmp");
return new FilePath(tmpTarget);
Expand All @@ -76,7 +77,7 @@ public FilePath call() throws IOException {
* @throws InterruptedException
* @throws
*/
public static Map<ManagedFile, FilePath> provisionConfigFiles(List<ManagedFile> managedFiles, AbstractBuild<?, ?> build, BuildListener listener) throws IOException, InterruptedException {
public static Map<ManagedFile, FilePath> provisionConfigFiles(List<ManagedFile> managedFiles, Run<?,?> build, FilePath workspace, TaskListener listener) throws IOException, InterruptedException {

final Map<ManagedFile, FilePath> file2Path = new HashMap<ManagedFile, FilePath>();
listener.getLogger().println("provisoning config files...");
Expand All @@ -97,20 +98,20 @@ public static Map<ManagedFile, FilePath> provisionConfigFiles(List<ManagedFile>

FilePath target = null;
if (createTempFile) {
target = ManagedFileUtil.createTempFile(build.getWorkspace().getChannel());
target = ManagedFileUtil.createTempFile(workspace.getChannel());
} else {

String expandedTargetLocation = managedFile.targetLocation;
try {
expandedTargetLocation = TokenMacro.expandAll(build, listener, managedFile.targetLocation);
expandedTargetLocation = build instanceof AbstractBuild ? TokenMacro.expandAll((AbstractBuild<?, ?>) build, listener, managedFile.targetLocation) : managedFile.targetLocation;
} catch (MacroEvaluationException e) {
listener.getLogger().println("[ERROR] failed to expand variables in target location '" + managedFile.targetLocation + "' : " + e.getMessage());
expandedTargetLocation = managedFile.targetLocation;
}

// Should treat given path as the actual filename unless it has a trailing slash (implying a
// directory) or path already exists in workspace as a directory.
target = new FilePath(build.getWorkspace(), expandedTargetLocation);
target = new FilePath(workspace, expandedTargetLocation);
String immediateFileName = expandedTargetLocation.substring(
expandedTargetLocation.lastIndexOf("/")+1);

Expand All @@ -133,12 +134,12 @@ public static Map<ManagedFile, FilePath> provisionConfigFiles(List<ManagedFile>
return file2Path;
}

private static String insertCredentialsInSettings(AbstractBuild<?, ?> build, Config configFile) throws IOException {
private static String insertCredentialsInSettings(Run<?,?> build, Config configFile) throws IOException {
String fileContent = configFile.content;

if (configFile instanceof HasServerCredentialMappings) {
HasServerCredentialMappings settings = (HasServerCredentialMappings) configFile;
final Map<String, StandardUsernameCredentials> resolvedCredentials = CredentialsHelper.resolveCredentials(build.getProject(), settings.getServerCredentialMappings());
final Map<String, StandardUsernameCredentials> resolvedCredentials = CredentialsHelper.resolveCredentials(build.getParent(), settings.getServerCredentialMappings());

if (!resolvedCredentials.isEmpty()) {
try {
Expand Down

0 comments on commit bcae981

Please sign in to comment.