Skip to content
Permalink
Browse files

added support for JENKINS-26966

  • Loading branch information...
jdamick committed May 18, 2015
1 parent 3314654 commit f4b8505e8788f8a591be9b56aaa90644d55aae03
@@ -8,7 +8,6 @@

package biz.neustar.jenkins.plugins.packer;

import com.google.common.base.Strings;
import hudson.AbortException;
import hudson.CopyOnWrite;
import hudson.EnvVars;
@@ -56,6 +55,7 @@
private String packerHome = "";
private String params = "";
private final boolean useDebug;
private final String changeDir;
private String templateMode = TemplateMode.GLOBAL.toMode();
private List<PackerFileEntry> fileEntries = Collections.emptyList();

@@ -66,7 +66,8 @@ public PackerPublisher(String name,
String packerHome,
String params,
List<PackerFileEntry> fileEntries,
boolean useDebug) {
boolean useDebug,
String changeDir) {

this.name = name;
this.jsonTemplate = jsonTemplate;
@@ -75,6 +76,7 @@ public PackerPublisher(String name,
this.params = params;
this.fileEntries = fileEntries;
this.useDebug = useDebug;
this.changeDir = changeDir;
}

public String getName() {
@@ -130,7 +132,7 @@ public String getGlobalTemplate() {
public static String createJsonTemplateTextTempFile(FilePath workspacePath, String contents) throws AbortException {
try {
LOGGER.info("jsonTemplateText: " + contents);
if (!Strings.isNullOrEmpty(contents)) {
if (Util.fixEmpty(contents) != null) {
FilePath jsonFile = workspacePath.createTextTempFile("packer", ".json", contents, false);
LOGGER.info("Using temp file: " + jsonFile.getRemote());
return jsonFile.getRemote();
@@ -152,6 +154,7 @@ public String getTemplateMode() {
return templateMode;
}

// TODO: @DataBoundSetter
public void setTemplateMode(String templateMode) {
this.templateMode = templateMode;
}
@@ -168,6 +171,11 @@ public boolean getUseDebug() {
return useDebug;
}

public String getChangeDir() {
return this.changeDir;
}


public boolean isFileTemplate() {
return TemplateMode.FILE.isMode(templateMode);
}
@@ -202,7 +210,7 @@ public String getRemotePackerExec(AbstractBuild build, Launcher launcher,

String home = getPackerHome();
String remoteExec = null;
if (Strings.isNullOrEmpty(home)) {
if (Util.fixEmpty(home) == null) {
PackerInstallation install = getInstallation();
try {
install = install.forNode(build.getBuiltOn(), listener)
@@ -278,16 +286,15 @@ public String createTempFileEntries(FilePath workspacePath) throws AbortExceptio
public boolean perform(AbstractBuild build, Launcher launcher,
BuildListener listener) {
ArgumentListBuilder args = new ArgumentListBuilder();
EnvVars env = null;
try {
args.add(getRemotePackerExec(build, launcher, listener)).add("build");

env = build.getEnvironment(listener);
EnvVars env = build.getEnvironment(listener);

PackerInstallation installation = getInstallation();

// mask the global params.
for (String param : addParamsAsArgs(Strings.nullToEmpty(installation.getParams()))) {
for (String param : addParamsAsArgs(Util.fixNull(installation.getParams()))) {
String addParam = param.trim();
if (addParam.length() > 0) {
args.add(Util.replaceMacro(addParam, env), true);
@@ -330,7 +337,7 @@ public boolean perform(AbstractBuild build, Launcher launcher,

try {
LOGGER.info("launch: " + args.toString());
if (launcher.launch().pwd(build.getWorkspace()).cmds(args).stdout(listener).join() == 0) {
if (launcher.launch().pwd(workingDir(build, env)).cmds(args).stdout(listener).join() == 0) {
listener.finished(Result.SUCCESS);
// parse the log to look for the image id

@@ -348,6 +355,13 @@ public boolean perform(AbstractBuild build, Launcher launcher,
return false;
}

protected FilePath workingDir(AbstractBuild build, EnvVars env) {
if (Util.fixEmpty(getChangeDir()) != null) {
return new FilePath(build.getWorkspace().getChannel(), Util.replaceMacro(getChangeDir(),env));
}
return build.getWorkspace();
}

protected static String convertException(Exception ex) {
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
@@ -357,13 +371,15 @@ protected static String convertException(Exception ex) {

// Adapted from FilePath since this method is not public
public static boolean isFilePathUnix(FilePath path) {
if(!path.isRemote())
if(!path.isRemote()) {
return File.pathSeparatorChar != ';';
}

String remote = path.getRemote();
// Windows absolute path is 'X:\...', so this is usually a good indication of Windows path
if(remote.length() > 3 && remote.charAt(1) == ':' && remote.charAt(2) == '\\')
if(remote.length() > 3 && remote.charAt(1) == ':' && remote.charAt(2) == '\\') {
return false;
}
return remote.indexOf("\\") == -1;
}

@@ -73,6 +73,10 @@
<f:entry title="${%Use Debug Option}" field="useDebug">
<f:checkbox />
</f:entry>
<f:entry title="${%Change to Directory}" field="changeDir"
description="Change to this directory prior to invoking packer">
<f:textbox />
</f:entry>

<f:entry title="${%File Entries}" field="fileEntries">
<f:repeatableProperty field="fileEntries" minimum="0" />
@@ -0,0 +1,5 @@
<div>
<p>
If set, the current directory will be changed to this before starting packer.
</p>
</div>
@@ -184,7 +184,7 @@ public void testPackerGlobalChecked() {

PackerPublisher plugin = new PackerPublisher(name,
jsonProjectTemplate, jsonText, PLUGIN_HOME,
localParams, emptyFileEntries, false);
localParams, emptyFileEntries, false, null);
plugin.setTemplateMode("");
assertTrue(plugin.isGlobalTemplateChecked());

@@ -206,7 +206,7 @@ public void testJobPluginTextInJob() {

PackerPublisher plugin = new PackerPublisher(name,
jsonProjectTemplate, jsonText, PLUGIN_HOME,
localParams, emptyFileEntries, false);
localParams, emptyFileEntries, false, null);

assertEquals(PLUGIN_HOME, plugin.getPackerHome());
// text in job initialization
@@ -227,7 +227,7 @@ public void testJobPluginFileInJob() {

PackerPublisher plugin = new PackerPublisher(name,
jsonFile, "{ \"here\": \"i am\"}", PLUGIN_HOME,
localParams, emptyFileEntries, false);
localParams, emptyFileEntries, false, null);

assertEquals(PLUGIN_HOME, plugin.getPackerHome());
// text in job initialization
@@ -249,7 +249,7 @@ public void testJobPluginGlobalInJob() {

PackerPublisher plugin = new PackerPublisher(name,
"somefile.json", "{ \"here\": \"i am\"}", PLUGIN_HOME,
localParams, emptyFileEntries, false);
localParams, emptyFileEntries, false, null);

PackerInstallation[] installations = new PackerInstallation[1];
installations[0] = installation;
@@ -277,7 +277,7 @@ public void testPluginInJobPathExec() throws Exception {

final String pluginHome = "bin";
PackerPublisher placeHolder = new PackerPublisher(name,
null, null, pluginHome, localParams, emptyFileEntries, false);
null, null, pluginHome, localParams, emptyFileEntries, false, null);

PackerInstallation[] installations = new PackerInstallation[1];
installations[0] = installation;
@@ -320,7 +320,7 @@ public void testPluginInJobAbsPathExec() throws Exception {
params, createTemplateModeJson(TemplateMode.TEXT, jsonText), emptyFileEntries, null);

PackerPublisher placeHolder = new PackerPublisher(name,
null, null, PLUGIN_HOME, localParams, emptyFileEntries, false);
null, null, PLUGIN_HOME, localParams, emptyFileEntries, false, null);

PackerInstallation[] installations = new PackerInstallation[1];
installations[0] = installation;
@@ -363,7 +363,7 @@ public void testPluginInJobWindowsPathExec() throws Exception {

final String pluginHome = "bin";
PackerPublisher placeHolder = new PackerPublisher(name,
null, null, pluginHome, localParams, emptyFileEntries, false);
null, null, pluginHome, localParams, emptyFileEntries, false, null);

PackerInstallation[] installations = new PackerInstallation[1];
installations[0] = installation;
@@ -413,7 +413,7 @@ public void testPluginInJobWindowsAbsPathExec() throws Exception {

final String pluginHome = "D:\\bin";
PackerPublisher placeHolder = new PackerPublisher(name,
null, null, pluginHome, localParams, emptyFileEntries, false);
null, null, pluginHome, localParams, emptyFileEntries, false, null);

PackerInstallation[] installations = new PackerInstallation[1];
installations[0] = installation;
@@ -471,7 +471,7 @@ public void testPluginBuild() throws Exception {
globalFileEntries.add(new PackerFileEntry("x509_cert", "in build"));
globalFileEntries.add(new PackerFileEntry("blah", "whatever"));
PackerPublisher placeHolder = new PackerPublisher(name,
null, null, pluginHome, "-var 'ami=123'", wkspFileEntries, false);
null, null, pluginHome, "-var 'ami=123'", wkspFileEntries, false, "${WORKSPACE}/blah/here");

PackerInstallation[] installations = new PackerInstallation[1];
installations[0] = installation;
@@ -519,11 +519,60 @@ public Proc answer(InvocationOnMock invocation) throws Throwable {
assertEquals("in build", Files.toString(new File(f), Charsets.UTF_8));

assertTrue(cmds.get(12).endsWith(".json"));

assertEquals(build.getWorkspace().getRemote() + "/blah/here", param.pwd().getRemote());

return procMock;
}
});

assertTrue(plugin.perform((AbstractBuild) build, launcherMock, buildListenerMock));
}

@Test
public void testPluginBuildNoChangeDir() throws Exception {
final String jsonText = "{ \"here\": \"i am\"}";

List<PackerFileEntry> globalFileEntries = new ArrayList<>();
PackerInstallation installation = new PackerInstallation(name, home,
"", createTemplateModeJson(TemplateMode.TEXT, jsonText), globalFileEntries, null);

final String pluginHome = "bin";

List<PackerFileEntry> wkspFileEntries = new ArrayList<>();
PackerPublisher placeHolder = new PackerPublisher(name,
null, null, pluginHome, "", wkspFileEntries, false, "");

PackerInstallation[] installations = new PackerInstallation[1];
installations[0] = installation;

placeHolder.getDescriptor().setInstallations(installations);

StaplerRequest mockReq = mock(StaplerRequest.class);
when(mockReq.bindJSON(any(Class.class), any(JSONObject.class))).thenReturn(placeHolder);

JSONObject formJson = new JSONObject();
formJson.put("templateMode", createTemplateModeJson(TemplateMode.TEXT, jsonText));
// formJson.put("useDebug", true);
PackerPublisher plugin = placeHolder.getDescriptor().newInstance(mockReq, formJson);

FreeStyleProject project = jenkins.createFreeStyleProject();
final FreeStyleBuild build = project.scheduleBuild2(0).get();

Launcher launcherMock = mock(Launcher.class);
BuildListener buildListenerMock = mock(BuildListener.class);

final Proc procMock = mock(Proc.class);
when(procMock.join()).thenReturn(0);
when(launcherMock.launch(any(Launcher.ProcStarter.class))).then(new Answer<Proc>() {
public Proc answer(InvocationOnMock invocation) throws Throwable {
Launcher.ProcStarter param = (Launcher.ProcStarter) invocation.getArguments()[0];
// should match workspace.
assertEquals(build.getWorkspace().getRemote(), param.pwd().getRemote());
return procMock;
}
});

assertTrue(plugin.perform((AbstractBuild) build, launcherMock, buildListenerMock));
}
}

0 comments on commit f4b8505

Please sign in to comment.
You can’t perform that action at this time.