Skip to content

Commit

Permalink
[JENKINS-30398] Add support for workflow plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
jcsirot committed Sep 16, 2015
1 parent 3aee5ae commit 3c3c1d2
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 36 deletions.
9 changes: 8 additions & 1 deletion pom.xml
Expand Up @@ -3,7 +3,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.565</version>
<version>1.580.1</version>
</parent>

<groupId>org.jenkins-ci.plugins</groupId>
Expand Down Expand Up @@ -61,6 +61,12 @@
<artifactId>ssh-credentials</artifactId>
<version>${ssh-credentials.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
<version>${workflow-step-api.version}</version>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
Expand Down Expand Up @@ -118,6 +124,7 @@
<maven-release-plugin.version>2.5.2</maven-release-plugin.version>
<ssh-credentials.version>1.10</ssh-credentials.version>
<credentials.version>1.16.1</credentials.version>
<workflow-step-api.version>1.4.2</workflow-step-api.version>
<junit.version>4.12</junit.version>
<mockito.version>1.10.19</mockito.version>
<assertj.version>1.7.1</assertj.version>
Expand Down
Expand Up @@ -26,6 +26,8 @@
import hudson.FilePath;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.util.ArgumentListBuilder;
import hudson.util.Secret;
import org.apache.commons.lang.StringUtils;
Expand All @@ -36,8 +38,8 @@
abstract class AbstractAnsibleInvocation<T extends AbstractAnsibleInvocation<T>> {

protected final EnvVars envVars;
protected final BuildListener listener;
protected final AbstractBuild<?, ?> build;
protected final TaskListener listener;
protected final Run<?, ?> build;
protected final Map<String, String> environment = new HashMap<String, String>();

protected String exe;
Expand All @@ -49,11 +51,13 @@ abstract class AbstractAnsibleInvocation<T extends AbstractAnsibleInvocation<T>>

private FilePath key = null;
private Inventory inventory;
private final FilePath ws;

protected AbstractAnsibleInvocation(String exe, AbstractBuild<?, ?> build, BuildListener listener)
protected AbstractAnsibleInvocation(String exe, Run<?, ?> build, FilePath ws, TaskListener listener)
throws IOException, InterruptedException, AnsibleInvocationException
{
this.build = build;
this.ws = ws;
this.envVars = build.getEnvironment(listener);
this.listener = listener;
this.exe = exe;
Expand All @@ -76,10 +80,11 @@ protected ArgumentListBuilder appendInventory(ArgumentListBuilder args)
throws IOException, InterruptedException, AnsibleInvocationException
{
if (inventory == null) {
throw new AnsibleInvocationException(
"The inventory of hosts and groups is not defined. Check the job configuration.");
// throw new AnsibleInvocationException(
// "The inventory of hosts and groups is not defined. Check the job configuration.");
return args;
}
inventory.addArgument(args, build.getWorkspace(), envVars, listener);
inventory.addArgument(args, ws, envVars, listener);
return args;
}

Expand Down Expand Up @@ -137,7 +142,7 @@ protected ArgumentListBuilder appendCredentials(ArgumentListBuilder args)
{
if (credentials instanceof SSHUserPrivateKey) {
SSHUserPrivateKey privateKeyCredentials = (SSHUserPrivateKey)credentials;
key = Utils.createSshKeyFile(key, build.getWorkspace(), privateKeyCredentials);
key = Utils.createSshKeyFile(key, ws, privateKeyCredentials);
args.add("--private-key").add(key);
args.add("-u").add(privateKeyCredentials.getUsername());
} else if (credentials instanceof UsernamePasswordCredentials) {
Expand Down Expand Up @@ -175,7 +180,9 @@ public boolean execute(CLIRunner runner) throws IOException, InterruptedExceptio
try {
return runner.execute(buildCommandLine(), environment);
} finally {
inventory.tearDown(listener);
if (inventory != null) {
inventory.tearDown(listener);
}
Utils.deleteTempFile(key, listener);
}
}
Expand Down
Expand Up @@ -96,7 +96,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen

try {
CLIRunner runner = new CLIRunner(build, launcher, listener);
String exe = AnsibleInstallation.getInstallation(ansibleName).getExecutable(AnsibleCommand.ANSIBLE, launcher);
String exe = AnsibleInstallation.getExecutable(ansibleName, AnsibleCommand.ANSIBLE, build.getBuiltOn(), listener, build.getEnvironment(listener));
AnsibleAdHocCommandInvocation invocation = new AnsibleAdHocCommandInvocation(exe , build, listener);
invocation.setHostPattern(hostPattern);
invocation.setInventory(inventory);
Expand Down
Expand Up @@ -35,7 +35,7 @@ public class AnsibleAdHocCommandInvocation extends AbstractAnsibleInvocation<Ans
protected AnsibleAdHocCommandInvocation(String exe, AbstractBuild<?, ?> build, BuildListener listener)
throws IOException, InterruptedException, AnsibleInvocationException
{
super(exe, build, listener);
super(exe, build, build.getWorkspace(), listener);
}

public AnsibleAdHocCommandInvocation setHostPattern(String hostPattern) {
Expand Down
Expand Up @@ -22,7 +22,9 @@

import hudson.EnvVars;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.EnvironmentSpecific;
import hudson.model.Node;
import hudson.model.TaskListener;
Expand All @@ -33,6 +35,7 @@
import hudson.tools.ToolProperty;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
import org.jenkinsci.remoting.RoleChecker;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

Expand All @@ -55,16 +58,50 @@ public AnsibleInstallation forNode(Node node, TaskListener log) throws IOExcepti
return new AnsibleInstallation(getName(), translateFor(node, log), getProperties().toList());
}

public String getExecutable(final AnsibleCommand command, Launcher launcher) throws IOException, InterruptedException {
return launcher.getChannel().call(new Callable<String, IOException>() {
public String call() throws IOException {
File exe = new File(getHome(), command.getName());
if (exe.exists()) {
return exe.getPath();
// public String getExecutable(final AnsibleCommand command, Launcher launcher) throws IOException, InterruptedException {
// return launcher.getChannel().call(new Callable<String, IOException>() {
// public String call() throws IOException {
// File exe = new File(getHome(), command.getName());
// if (exe.exists()) {
// return exe.getPath();
// }
// return null;
// }
//
// @Override
// public void checkRoles(RoleChecker checker) throws SecurityException {
// //To change body of implemented methods use File | Settings | File Templates.
// }
// });
// }

public static String getExecutable(String name, AnsibleCommand command, Node node, TaskListener listener, EnvVars env) throws IOException, InterruptedException {
if (name != null) {
Jenkins j = Jenkins.getInstance();
if (j != null) {
for (AnsibleInstallation tool : j.getDescriptorByType(DescriptorImpl.class).getInstallations()) {
if (tool.getName().equals(name)) {
if (node != null) {
tool = tool.forNode(node, listener);
}
if (env != null) {
tool = tool.forEnvironment(env);
}
String home = Util.fixEmpty(tool.getHome());
if (home != null) {
if (node != null) {
FilePath homePath = node.createPath(home);
if (homePath != null) {
return homePath.child(command.getName()).getRemote();
}
}
return home + "/" + command.getName();
}
}
}
return null;
}
});
}
return command.getName();
}

public static AnsibleInstallation[] allInstallations() {
Expand All @@ -89,6 +126,14 @@ public static AnsibleInstallation getInstallation(String ansibleInstallation) th
throw new IOException("Ansible not found");
}

@Override
public void buildEnvVars(EnvVars env) {
String home = Util.fixEmpty(getHome());
if (home != null) {
env.put("PATH+ANSIBLE", home);
}
}

@Extension
public static class DescriptorImpl extends ToolDescriptor<AnsibleInstallation> {

Expand Down
Expand Up @@ -98,7 +98,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListen
{
try {
CLIRunner runner = new CLIRunner(build, launcher, listener);
String exe = AnsibleInstallation.getInstallation(ansibleName).getExecutable(AnsibleCommand.ANSIBLE_PLAYBOOK, launcher);
String exe = AnsibleInstallation.getExecutable(ansibleName, AnsibleCommand.ANSIBLE_PLAYBOOK, build.getBuiltOn(), listener, build.getEnvironment(listener));
AnsiblePlaybookInvocation invocation = new AnsiblePlaybookInvocation(exe, build, listener);
invocation.setPlaybook(playbook);
invocation.setInventory(inventory);
Expand Down
Expand Up @@ -17,9 +17,12 @@

import java.io.IOException;

import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.util.ArgumentListBuilder;
import org.apache.commons.lang.StringUtils;

Expand All @@ -37,7 +40,13 @@ public class AnsiblePlaybookInvocation extends AbstractAnsibleInvocation<Ansible
protected AnsiblePlaybookInvocation(String exe, AbstractBuild<?, ?> build, BuildListener listener)
throws IOException, InterruptedException, AnsibleInvocationException
{
super(exe, build, listener);
this(exe, build, build.getWorkspace(), listener);
}

public AnsiblePlaybookInvocation(String exe, Run<?, ?> build, FilePath ws, TaskListener listener)
throws IOException, InterruptedException, AnsibleInvocationException
{
super(exe, build, ws, listener);
}

public AnsiblePlaybookInvocation setPlaybook(String playbook) {
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/org/jenkinsci/plugins/ansible/CLIRunner.java
Expand Up @@ -3,9 +3,12 @@
import java.io.IOException;
import java.util.Map;

import hudson.FilePath;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.BuildListener;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.util.ArgumentListBuilder;

/**
Expand All @@ -15,23 +18,32 @@
* Time: 22:56
* To change this template use File | Settings | File Templates.
*/
class CLIRunner
public class CLIRunner
{
private final Launcher launcher;
private final AbstractBuild<?, ?> build;
private final BuildListener listener;
private final Run<?, ?> build;
private final TaskListener listener;
private final FilePath ws;

public CLIRunner(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) {
this.launcher = launcher;
this.build = build;
this.listener = listener;
this.ws = build.getWorkspace();
}

public CLIRunner(Run<?, ?> build, FilePath ws, Launcher launcher, TaskListener listener) {
this.launcher = launcher;
this.build = build;
this.listener = listener;
this.ws = ws;
}

public boolean execute(ArgumentListBuilder args, Map<String, String> environment)
throws IOException, InterruptedException
{
return launcher.launch()
.pwd(build.getWorkspace())
.pwd(ws)
.envs(environment)
.cmds(args)
.stdout(listener).join() == 0;
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/org/jenkinsci/plugins/ansible/Inventory.java
Expand Up @@ -22,6 +22,7 @@
import hudson.model.BuildListener;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.TaskListener;
import hudson.util.ArgumentListBuilder;
import jenkins.model.Jenkins;

Expand All @@ -41,24 +42,24 @@ public Descriptor<Inventory> getDescriptor() {

protected abstract InventoryHandler getHandler();

public void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, BuildListener listener)
public void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, TaskListener listener)
throws InterruptedException, IOException
{
getHandler().addArgument(args, workspace, envVars, listener);
}

public void tearDown(BuildListener listener) throws InterruptedException, IOException {
public void tearDown(TaskListener listener) throws InterruptedException, IOException {
getHandler().tearDown(listener);
}

public abstract static class InventoryDescriptor extends Descriptor<Inventory> { }

protected static interface InventoryHandler {

void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, BuildListener listener)
void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, TaskListener listener)
throws InterruptedException, IOException;

void tearDown(BuildListener listener) throws InterruptedException, IOException;
void tearDown(TaskListener listener) throws InterruptedException, IOException;
}

}
Expand Up @@ -21,6 +21,7 @@
import hudson.Extension;
import hudson.FilePath;
import hudson.model.BuildListener;
import hudson.model.TaskListener;
import hudson.util.ArgumentListBuilder;
import org.kohsuke.stapler.DataBoundConstructor;

Expand All @@ -44,14 +45,14 @@ public InventoryContent(String content, boolean dynamic) {
protected InventoryHandler getHandler()
{
return new InventoryHandler() {
public void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, BuildListener listener)
public void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, TaskListener listener)
throws InterruptedException, IOException
{
inventory = createInventoryFile(inventory, workspace, envVars.expand(content));
args.add("-i").add(inventory);
}

public void tearDown(BuildListener listener) throws InterruptedException, IOException {
public void tearDown(TaskListener listener) throws InterruptedException, IOException {
Utils.deleteTempFile(inventory, listener);
}

Expand Down
Expand Up @@ -19,6 +19,7 @@
import hudson.Extension;
import hudson.FilePath;
import hudson.model.BuildListener;
import hudson.model.TaskListener;
import hudson.util.ArgumentListBuilder;
import org.kohsuke.stapler.DataBoundConstructor;

Expand All @@ -39,13 +40,13 @@ protected InventoryHandler getHandler()
{
return new InventoryHandler()
{
public void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, BuildListener listener)
public void addArgument(ArgumentListBuilder args, FilePath workspace, EnvVars envVars, TaskListener listener)
{
String expandedPath = envVars.expand(InventoryPath.this.path);
args.add("-i").add(expandedPath);
}

public void tearDown(BuildListener listener)
public void tearDown(TaskListener listener)
{
}
};
Expand Down

0 comments on commit 3c3c1d2

Please sign in to comment.