You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2013/07/24 21:25:38 UTC

[1/4] git commit: Removed the ability to manually provision Jenkins slaves.

Updated Branches:
  refs/heads/master 552017489 -> 26f252ec1


Removed the ability to manually provision Jenkins slaves.

Review: https://reviews.apache.org/r/12846


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/3489d012
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/3489d012
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/3489d012

Branch: refs/heads/master
Commit: 3489d012af5611b58ef027b5a3d49f9c20d24932
Parents: 5520174
Author: Vinod Kone <vi...@twitter.com>
Authored: Mon Jul 22 22:27:08 2013 -0700
Committer: Vinod Kone <vi...@twitter.com>
Committed: Wed Jul 24 12:25:10 2013 -0700

----------------------------------------------------------------------
 jenkins/Makefile.am                                     |  1 -
 .../plugins/mesos/MesosCloud/computerSet.jelly          | 12 ------------
 2 files changed, 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/3489d012/jenkins/Makefile.am
----------------------------------------------------------------------
diff --git a/jenkins/Makefile.am b/jenkins/Makefile.am
index f704d0e..2ddded2 100644
--- a/jenkins/Makefile.am
+++ b/jenkins/Makefile.am
@@ -23,7 +23,6 @@ EXTRA_DIST = pom.xml										\
 	src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java			\
 	src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java				\
 	src/main/resources/index.jelly								\
-	src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/computerSet.jelly		\
 	src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/config.jelly			\
 	src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/help-master.html		\
 	src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly

http://git-wip-us.apache.org/repos/asf/mesos/blob/3489d012/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/computerSet.jelly
----------------------------------------------------------------------
diff --git a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/computerSet.jelly b/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/computerSet.jelly
deleted file mode 100644
index 9d1ec6c..0000000
--- a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/computerSet.jelly
+++ /dev/null
@@ -1,12 +0,0 @@
-<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
-  <j:if test="${it.hasPermission(it.PROVISION)}">
-    <tr>
-      <td />
-      <td colspan="${monitors.size()+1}">
-        <f:form action="${rootURL}/cloud/${it.name}/provision" method="post" name="provision">
-          <input type="submit" class="mesos-provision-button" value="${%Provision via Mesos}" />
-        </f:form>
-      </td>
-    </tr>
-  </j:if>
-</j:jelly>
\ No newline at end of file


[2/4] git commit: Fixed Slave, Cloud and Retention strategy for Jenkins.

Posted by vi...@apache.org.
Fixed Slave, Cloud and Retention strategy for Jenkins.

Review: https://reviews.apache.org/r/12847


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2996a80d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2996a80d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2996a80d

Branch: refs/heads/master
Commit: 2996a80d4a9ce5978d72d8aa27039ac92be84bff
Parents: 3489d01
Author: Vinod Kone <vi...@twitter.com>
Authored: Tue Jul 23 01:20:33 2013 -0700
Committer: Vinod Kone <vi...@twitter.com>
Committed: Wed Jul 24 12:25:11 2013 -0700

----------------------------------------------------------------------
 .../org/jenkinsci/plugins/mesos/MesosCloud.java | 10 +---
 .../plugins/mesos/MesosRetentionStrategy.java   |  4 +-
 .../org/jenkinsci/plugins/mesos/MesosSlave.java | 59 ++++++++++----------
 .../mesos/MesosSlave/configure-entries.jelly    | 24 ++------
 4 files changed, 37 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/2996a80d/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
index 60154e3..dcde9a3 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
@@ -40,6 +40,8 @@ public class MesosCloud extends Cloud {
   private String master;
   private String description;
   private String labelString = "mesos";
+  private String idleTerminationMinutes = "1"; // TODO(vinod): Make this configurable.
+
   private static String staticMaster;
 
   private static final Logger LOGGER = Logger.getLogger(MesosCloud.class.getName());
@@ -109,13 +111,7 @@ public class MesosCloud extends Cloud {
 
   private MesosSlave doProvision(int numExecutors) throws Descriptor.FormException, IOException {
     String name = "mesos-jenkins-" + UUID.randomUUID().toString();
-    String nodeDescription = labelString;
-    String remoteFS = "jenkins";
-    Mode mode = Mode.NORMAL;
-    List<? extends NodeProperty<?>> nodeProperties = null;
-
-    return new MesosSlave(name, nodeDescription, remoteFS, numExecutors, mode, labelString,
-        nodeProperties, "1", "0");
+    return new MesosSlave(name, ""+numExecutors, labelString, idleTerminationMinutes);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/mesos/blob/2996a80d/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
index 17da814..ae6c78c 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
@@ -28,15 +28,13 @@ public class MesosRetentionStrategy extends RetentionStrategy<MesosComputer> {
   private static final Logger LOGGER = Logger
       .getLogger(MesosRetentionStrategy.class.getName());
 
-  @DataBoundConstructor
   public MesosRetentionStrategy(String idleTerminationMinutes) {
     int value = IDLE_TERMINATION_MINUTES;
     if (idleTerminationMinutes != null && idleTerminationMinutes.trim() != "") {
       try {
         value = Integer.parseInt(idleTerminationMinutes);
       } catch (NumberFormatException nfe) {
-        LOGGER.info("Malformed default idleTermination value: "
-            + idleTerminationMinutes);
+        LOGGER.info("Malformed idleTermination value: " + idleTerminationMinutes);
       }
     }
     this.idleTerminationMinutes = value;

http://git-wip-us.apache.org/repos/asf/mesos/blob/2996a80d/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
index eed0ba3..7912129 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
@@ -1,6 +1,8 @@
 package org.jenkinsci.plugins.mesos;
 
+import hudson.Extension;
 import hudson.model.Computer;
+import hudson.model.Descriptor;
 import hudson.model.Descriptor.FormException;
 import hudson.model.Hudson;
 import hudson.model.Slave;
@@ -21,40 +23,22 @@ public class MesosSlave extends Slave {
   private static final Logger LOGGER = Logger.getLogger(MesosSlave.class
       .getName());
 
-  private final String idleTerminationMinutes;
-  private final String limitedBuildCount;
-  private final String clusterId;
-
   @DataBoundConstructor
-  public MesosSlave(String name, String description, String remoteFS,
-      int numExecutors, Mode mode, String labelString,
-      List<? extends NodeProperty<?>> nodeProperties,
-      String idleTerminationMinutes, String limitedBuildCount)
-      throws FormException, IOException {
-
-    this(name, description, remoteFS, numExecutors, Mode.NORMAL, labelString,
-        new MesosComputerLauncher(name), null, Collections
-            .<NodeProperty<?>> emptyList(), idleTerminationMinutes,
-        limitedBuildCount);
-  }
-
-  public MesosSlave(String name, String nodeDescription, String remoteFS,
-      int numExecutors, Mode mode, String labelString,
-      ComputerLauncher launcher,
-      RetentionStrategy<MesosComputer> retentionStrategy,
-      List<? extends NodeProperty<?>> nodeProperties,
-      String idleTerminationMinutes, String limitedBuildCount)
-      throws FormException, IOException {
-
-    super(name, nodeDescription, remoteFS, numExecutors, Mode.NORMAL,
-        labelString, launcher, new MesosRetentionStrategy(
-            idleTerminationMinutes), Collections.<NodeProperty<?>> emptyList());
+  public MesosSlave(
+      String name, String numExecutors, String labelString, String idleTerminationMinutes)
+      throws FormException, IOException
+  {
+    super(name,
+          labelString, // node description.
+          "jenkins",   // remoteFS.
+          numExecutors,
+          Mode.NORMAL,
+          labelString, // Label.
+          new MesosComputerLauncher(name),
+          new MesosRetentionStrategy(idleTerminationMinutes),
+          Collections.<NodeProperty<?>> emptyList());
 
     LOGGER.info("Constructing Mesos slave");
-
-    this.idleTerminationMinutes = idleTerminationMinutes;
-    this.limitedBuildCount = limitedBuildCount;
-    this.clusterId = null;
   }
 
   public void terminate() {
@@ -75,6 +59,19 @@ public class MesosSlave extends Slave {
     }
   }
 
+  @Override
+  public DescriptorImpl getDescriptor() {
+    return (DescriptorImpl) super.getDescriptor();
+  }
+
+  @Extension
+  public static class DescriptorImpl extends SlaveDescriptor {
+    @Override
+    public String getDisplayName() {
+      return "Mesos Slave";
+    }
+  }
+
   private String getInstanceId() {
     return getNodeName();
   }

http://git-wip-us.apache.org/repos/asf/mesos/blob/2996a80d/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
----------------------------------------------------------------------
diff --git a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly b/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
index 24448a8..18a250d 100644
--- a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
+++ b/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
@@ -1,29 +1,15 @@
 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
 
-        <f:entry title="${%Mesos Cluster ID}" field="mesosClusterID">
-          <f:readOnlyTextbox />
-        </f:entry>
-
-        <f:entry title="${%Description}" >
-          <f:textbox field="description" />
-        </f:entry>
-
         <f:entry title="${%# of executors}" field="numExecutors">
-          <f:textbox />
+          <f:readOnlyTextbox />
         </f:entry>
 
         <f:entry title="${%Labels}" field="labelString">
-          <f:textbox />
+          <f:readOnlyTextbox />
         </f:entry>
 
-        <f:entry title="${%Idle termination time}" field="idleTerminationMinutes">
-            <f:textbox />
+        <f:entry title="${%Idle Termination Minutes}" field="idleTerminationMinutes">
+          <f:readOnlyTextbox />
         </f:entry>
 
-       <f:entry title="${%Terminate After Limited Builds}" description="${%Number of builds to allow before terminate the slave; use 0 for NEVER.}">
-
-       <f:textbox default="0" field="limitedBuildCount"/>
-
-   </f:entry>
-
-</j:jelly>
\ No newline at end of file
+</j:jelly>


[4/4] git commit: Fixed JenkinsScheduler to not crash when the Mesos native library is not bundled with the plugin.

Posted by vi...@apache.org.
Fixed JenkinsScheduler to not crash when the Mesos
native library is not bundled with the plugin.

Review: https://reviews.apache.org/r/12884


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/869beade
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/869beade
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/869beade

Branch: refs/heads/master
Commit: 869beade1a771312d12d69a8b37c0c8609c6a2e5
Parents: 2996a80
Author: Vinod Kone <vi...@twitter.com>
Authored: Tue Jul 23 15:45:38 2013 -0700
Committer: Vinod Kone <vi...@twitter.com>
Committed: Wed Jul 24 12:25:11 2013 -0700

----------------------------------------------------------------------
 .../org/jenkinsci/plugins/mesos/JenkinsScheduler.java     | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/869beade/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
index ce33d57..a68e1ea 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
@@ -76,7 +76,15 @@ public class JenkinsScheduler implements Scheduler {
       MESOS_NATIVE_LIBRARY = resourceURL.getPath() + "libmesos.dylib";
     }
 
-    MesosNativeLibrary.load(MESOS_NATIVE_LIBRARY);
+    // First, we attempt to load the library from the plugin directory.
+    // If unsuccessful, we attempt to load using 'MesosNativeLibrary.load()'.
+    try {
+      MesosNativeLibrary.load(MESOS_NATIVE_LIBRARY);
+    } catch (UnsatisfiedLinkError error) {
+      LOGGER.warning("Failed to load native Mesos library from '" + MESOS_NATIVE_LIBRARY +
+                     "': " + error.getMessage());
+      MesosNativeLibrary.load();
+    }
 
     // Start the framework.
     new Thread(new Runnable() {


[3/4] git commit: Refactored Jenkins to make resources configurable.

Posted by vi...@apache.org.
Refactored Jenkins to make resources configurable.

Review: https://reviews.apache.org/r/12890


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/26f252ec
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/26f252ec
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/26f252ec

Branch: refs/heads/master
Commit: 26f252ec1dc44620434e09c93b9c8527a21218cf
Parents: 869bead
Author: Vinod Kone <vi...@twitter.com>
Authored: Tue Jul 23 20:23:57 2013 -0700
Committer: Vinod Kone <vi...@twitter.com>
Committed: Wed Jul 24 12:25:11 2013 -0700

----------------------------------------------------------------------
 .../plugins/mesos/JenkinsScheduler.java         | 23 ++++-----
 .../java/org/jenkinsci/plugins/mesos/Mesos.java | 10 ++--
 .../org/jenkinsci/plugins/mesos/MesosCloud.java | 52 ++++++++++----------
 .../plugins/mesos/MesosComputerLauncher.java    |  5 +-
 .../plugins/mesos/MesosRetentionStrategy.java   | 15 +-----
 .../org/jenkinsci/plugins/mesos/MesosSlave.java | 22 +++++++--
 .../plugins/mesos/MesosCloud/config.jelly       | 22 ++++++++-
 .../mesos/MesosSlave/configure-entries.jelly    | 12 ++---
 8 files changed, 92 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
index a68e1ea..a52fc0f 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/JenkinsScheduler.java
@@ -33,14 +33,11 @@ import org.apache.mesos.Scheduler;
 import org.apache.mesos.SchedulerDriver;
 
 public class JenkinsScheduler implements Scheduler {
-  private static final int JENKINS_SLAVE_CPUS = 1;
-
-  // TODO(vinod): Revert these to real values when using in production.
-  private static final int JENKINS_SLAVE_MEM = 512;
-  private static final int JENKINS_EXECUTOR_MEM = 100;
-
   private static final String SLAVE_JAR_URI_SUFFIX = "jnlpJars/slave.jar";
 
+  // We allocate 10% more memory to the Mesos task to account for the JVM overhead.
+  private static final double JVM_MEM_OVERHEAD_FACTOR = 0.1;
+
   private static final String SLAVE_COMMAND_FORMAT =
       "java -DHUDSON_HOME=jenkins -server -Xmx%dm -Xms16m -XX:+UseConcMarkSweepGC " +
       "-Djava.net.preferIPv4Stack=true -jar slave.jar  -jnlpUrl %s";
@@ -59,6 +56,7 @@ public class JenkinsScheduler implements Scheduler {
 
     this.jenkinsMaster = jenkinsMaster;
     this.mesosMaster = mesosMaster;
+
     requests = new LinkedList<Request>();
     results = new HashMap<TaskID, Result>();
   }
@@ -114,7 +112,7 @@ public class JenkinsScheduler implements Scheduler {
   }
 
   public void requestJenkinsSlave(Mesos.SlaveRequest request, Mesos.SlaveResult result) {
-    LOGGER.info("Enqueuing jenkins slave request " + request.executors);
+    LOGGER.info("Enqueuing jenkins slave request");
     requests.add(new Request(request, result));
   }
 
@@ -212,8 +210,8 @@ public class JenkinsScheduler implements Scheduler {
     if (mem < 0)  LOGGER.severe("No mem resource present");
 
     // Check for sufficient cpu and memory resources in the offer.
-    double requestedCpus = JENKINS_SLAVE_CPUS * request.request.executors;
-    double requestedMem = JENKINS_SLAVE_MEM + (request.request.executors * JENKINS_EXECUTOR_MEM);
+    double requestedCpus = request.request.cpus;
+    double requestedMem = (1 + JVM_MEM_OVERHEAD_FACTOR) * request.request.mem;
 
     if (requestedCpus <= cpus && requestedMem <= mem) {
       return true;
@@ -246,7 +244,7 @@ public class JenkinsScheduler implements Scheduler {
                 .setType(Value.Type.SCALAR)
                 .setScalar(
                     Value.Scalar.newBuilder()
-                        .setValue(JENKINS_SLAVE_CPUS + request.request.executors).build()).build())
+                        .setValue(request.request.cpus).build()).build())
         .addResources(
             Resource
                 .newBuilder()
@@ -255,14 +253,13 @@ public class JenkinsScheduler implements Scheduler {
                 .setScalar(
                     Value.Scalar
                         .newBuilder()
-                        .setValue(
-                            JENKINS_SLAVE_MEM + JENKINS_EXECUTOR_MEM * request.request.executors)
+                        .setValue((1 + JVM_MEM_OVERHEAD_FACTOR) * request.request.mem)
                         .build()).build())
         .setCommand(
             CommandInfo
                 .newBuilder()
                 .setValue(
-                    String.format(SLAVE_COMMAND_FORMAT, JENKINS_SLAVE_MEM,
+                    String.format(SLAVE_COMMAND_FORMAT, request.request.mem,
                         getJnlpUrl(request.request.slave.name)))
                 .addUris(
                     CommandInfo.URI.newBuilder().setValue(

http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/java/org/jenkinsci/plugins/mesos/Mesos.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/Mesos.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/Mesos.java
index f5234d4..61a226e 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/Mesos.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/Mesos.java
@@ -13,11 +13,13 @@ public abstract class Mesos {
 
   public static class SlaveRequest {
     JenkinsSlave slave;
-    int executors;
+    final int cpus;
+    final int mem;
 
-    public SlaveRequest(JenkinsSlave _slave, int _executors) {
-      this.slave = _slave;
-      this.executors = _executors;
+    public SlaveRequest(JenkinsSlave slave, int cpus, int mem) {
+      this.slave = slave;
+      this.cpus = cpus;
+      this.mem = mem;
     }
   }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
index dcde9a3..a096b12 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosCloud.java
@@ -39,17 +39,34 @@ public class MesosCloud extends Cloud {
 
   private String master;
   private String description;
-  private String labelString = "mesos";
-  private String idleTerminationMinutes = "1"; // TODO(vinod): Make this configurable.
+
+  // TODO(vinod): Let the default values in MesosCloud/confg.jelly be inherited from here.
+  private int slaveCpus = 1;
+  private int slaveMem = 512; // MB.
+  private int executorCpus = 1;
+  private int executorMem = 128; // MB.
+  private int idleTerminationMinutes = 3;
+
+  private final String labelString = "mesos";
 
   private static String staticMaster;
 
   private static final Logger LOGGER = Logger.getLogger(MesosCloud.class.getName());
 
   @DataBoundConstructor
-  public MesosCloud(String master, String description) {
+  public MesosCloud(String master, String description, int slaveCpus,
+      int slaveMem, int executorCpus, int executorMem, int idleTerminationMinutes)
+          throws NumberFormatException {
     super("MesosCloud");
 
+    this.master = master;
+    this.description = description;
+    this.slaveCpus = slaveCpus;
+    this.slaveMem = slaveMem;
+    this.executorCpus = executorCpus;
+    this.executorMem = executorMem;
+    this.idleTerminationMinutes = idleTerminationMinutes;
+
     // Restart the scheduler if the master has changed or a scheduler is not up.
     if (!master.equals(staticMaster) || !Mesos.getInstance().isSchedulerRunning()) {
       if (!master.equals(staticMaster)) {
@@ -64,22 +81,19 @@ public class MesosCloud extends Cloud {
       LOGGER.info("Mesos master has not changed, leaving the scheduler running");
     }
 
-    this.master = master;
-    this.description = description;
-
-    staticMaster = this.master;
+    staticMaster = master;
   }
 
   @Override
   public Collection<PlannedNode> provision(Label label, int excessWorkload) {
-    final int numExecutors = 1;
     List<PlannedNode> list = new ArrayList<PlannedNode>();
-
+    final int numExecutors = excessWorkload;
     try {
       list.add(new PlannedNode(this.getDisplayName(), Computer.threadPoolForRemoting
           .submit(new Callable<Node>() {
             public Node call() throws Exception {
-              // TODO: record the output somewhere
+              // TODO(vinod): Instead of launching one slave with 'excessWorkload' executors,
+              // launch multiple slaves with fewer executors per slave.
               MesosSlave s = doProvision(numExecutors);
               Hudson.getInstance().addNode(s);
               return s;
@@ -94,24 +108,10 @@ public class MesosCloud extends Cloud {
     return list;
   }
 
-  public void doProvision(StaplerRequest req, StaplerResponse rsp) throws ServletException,
-      IOException, FormException {
-    checkPermission(PROVISION);
-    LOGGER.log(Level.INFO, "Create a new node by user request");
-
-    try {
-      MesosSlave node = doProvision(1);
-      Hudson.getInstance().addNode(node);
-
-      rsp.sendRedirect2(req.getContextPath() + "/computer/" + node.getNodeName());
-    } catch (Exception e) {
-      sendError(e.getMessage(), req, rsp);
-    }
-  }
-
   private MesosSlave doProvision(int numExecutors) throws Descriptor.FormException, IOException {
     String name = "mesos-jenkins-" + UUID.randomUUID().toString();
-    return new MesosSlave(name, ""+numExecutors, labelString, idleTerminationMinutes);
+    return new MesosSlave(name, numExecutors, labelString, slaveCpus, slaveMem,
+        executorCpus, executorMem, idleTerminationMinutes);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosComputerLauncher.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosComputerLauncher.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosComputerLauncher.java
index ca66ab8..c752254 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosComputerLauncher.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosComputerLauncher.java
@@ -55,8 +55,9 @@ public class MesosComputerLauncher extends ComputerLauncher {
     }
 
     // Create the request.
-    int numExecutors = computer.getNode().getNumExecutors();
-    Mesos.SlaveRequest request = new Mesos.SlaveRequest(new JenkinsSlave(name), numExecutors);
+    int cpus = computer.getNode().getCpus();
+    int mem = computer.getNode().getMem();
+    Mesos.SlaveRequest request = new Mesos.SlaveRequest(new JenkinsSlave(name), cpus, mem);
 
     // Launch the jenkins slave.
     final Lock lock = new ReentrantLock();

http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
index ae6c78c..b0b6d8a 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosRetentionStrategy.java
@@ -22,22 +22,11 @@ public class MesosRetentionStrategy extends RetentionStrategy<MesosComputer> {
    */
   public final int idleTerminationMinutes;
 
-  // Since a Mesos task is fast to start/stop we use a default value of 1 min.
-  private final int IDLE_TERMINATION_MINUTES = 1;
-
   private static final Logger LOGGER = Logger
       .getLogger(MesosRetentionStrategy.class.getName());
 
-  public MesosRetentionStrategy(String idleTerminationMinutes) {
-    int value = IDLE_TERMINATION_MINUTES;
-    if (idleTerminationMinutes != null && idleTerminationMinutes.trim() != "") {
-      try {
-        value = Integer.parseInt(idleTerminationMinutes);
-      } catch (NumberFormatException nfe) {
-        LOGGER.info("Malformed idleTermination value: " + idleTerminationMinutes);
-      }
-    }
-    this.idleTerminationMinutes = value;
+  public MesosRetentionStrategy(int idleTerminationMinutes) {
+    this.idleTerminationMinutes = idleTerminationMinutes;
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
----------------------------------------------------------------------
diff --git a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
index 7912129..9848ae9 100644
--- a/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
+++ b/jenkins/src/main/java/org/jenkinsci/plugins/mesos/MesosSlave.java
@@ -20,27 +20,41 @@ import org.kohsuke.stapler.DataBoundConstructor;
 
 public class MesosSlave extends Slave {
 
+  private final int cpus;
+  private final int mem;
+
   private static final Logger LOGGER = Logger.getLogger(MesosSlave.class
       .getName());
 
   @DataBoundConstructor
-  public MesosSlave(
-      String name, String numExecutors, String labelString, String idleTerminationMinutes)
-      throws FormException, IOException
+  public MesosSlave(String name, int numExecutors, String labelString,
+      int slaveCpus, int slaveMem, int executorCpus, int executorMem,
+      int idleTerminationMinutes) throws FormException, IOException
   {
     super(name,
           labelString, // node description.
           "jenkins",   // remoteFS.
-          numExecutors,
+          "" + numExecutors,
           Mode.NORMAL,
           labelString, // Label.
           new MesosComputerLauncher(name),
           new MesosRetentionStrategy(idleTerminationMinutes),
           Collections.<NodeProperty<?>> emptyList());
 
+    this.cpus = slaveCpus + (numExecutors * executorCpus);
+    this.mem = slaveMem + (numExecutors * executorMem);
+
     LOGGER.info("Constructing Mesos slave");
   }
 
+  public int getCpus() {
+    return cpus;
+  }
+
+  public int getMem() {
+    return mem;
+  }
+
   public void terminate() {
     LOGGER.info("Terminating slave " + getNodeName());
     try {

http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/config.jelly
----------------------------------------------------------------------
diff --git a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/config.jelly b/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/config.jelly
index a2e754e..0e2a6cb 100644
--- a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/config.jelly
+++ b/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosCloud/config.jelly
@@ -8,5 +8,25 @@
         <f:textbox field="description" />
     </f:entry>
 
+    <f:entry title="${%Jenkins Slave CPUs}">
+        <f:number field="slaveCpus" clazz="required positive-number"  value="1"/>
+    </f:entry>
+
+    <f:entry title="${%Jenkins Slave Memory in MB}">
+        <f:number field="slaveMem" clazz="required positive-number" value="512"/>
+    </f:entry>
+
+    <f:entry title="${%Jenkins Executor CPUs}">
+        <f:number field="executorCpus" clazz="required number" value="1"/>
+    </f:entry>
+
+    <f:entry title="${%Jenkins Executor Memory in MB}">
+        <f:number field="executorMem" clazz="required positive-number" value="128"/>
+    </f:entry>
+
+   <f:entry title="${%Idle Termination Minutes}">
+        <f:number field="idleTerminationMinutes" clazz="required positive-number" value="3"/>
+    </f:entry>
+
     <f:validateButton title="${%Test Connection}" progress="${%Testing...}" method="testConnection" with="master"/>
-</j:jelly>
\ No newline at end of file
+</j:jelly>

http://git-wip-us.apache.org/repos/asf/mesos/blob/26f252ec/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
----------------------------------------------------------------------
diff --git a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly b/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
index 18a250d..d671731 100644
--- a/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
+++ b/jenkins/src/main/resources/org/jenkinsci/plugins/mesos/MesosSlave/configure-entries.jelly
@@ -1,15 +1,15 @@
 <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
 
-        <f:entry title="${%# of executors}" field="numExecutors">
-          <f:readOnlyTextbox />
+        <f:entry title="${%# of executors}">
+          <f:readOnlyTextbox field="numExecutors" clazz="positive-number"/>
         </f:entry>
 
-        <f:entry title="${%Labels}" field="labelString">
-          <f:readOnlyTextbox />
+        <f:entry title="${%Labels}">
+          <f:readOnlyTextbox field="labelString"/>
         </f:entry>
 
-        <f:entry title="${%Idle Termination Minutes}" field="idleTerminationMinutes">
-          <f:readOnlyTextbox />
+        <f:entry title="${%Idle Termination Minutes}">
+          <f:readOnlyTextbox field="idleTerminationMinutes" clazz="positive-number"/>
         </f:entry>
 
 </j:jelly>