You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by wf...@apache.org on 2017/10/11 00:29:11 UTC

[2/8] aurora git commit: Use a simpler command line argument system

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/resources/ResourceSettings.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/resources/ResourceSettings.java b/src/main/java/org/apache/aurora/scheduler/resources/ResourceSettings.java
index 4e2c425..0ca83b6 100644
--- a/src/main/java/org/apache/aurora/scheduler/resources/ResourceSettings.java
+++ b/src/main/java/org/apache/aurora/scheduler/resources/ResourceSettings.java
@@ -15,8 +15,8 @@ package org.apache.aurora.scheduler.resources;
 
 import java.util.function.Supplier;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 
 /**
  * Control knobs for how Aurora treats different resource types.
@@ -25,17 +25,18 @@ import org.apache.aurora.common.args.CmdLine;
  * and then inject them via 'settings' classes. Unfortunately, this does not work here as we
  * would need to perform the injection into the ResourceType enum. Enums are picky in that regard.
  */
-final class ResourceSettings {
+@Parameters(separators = "=")
+public class ResourceSettings {
 
-  @CmdLine(name = "enable_revocable_cpus", help = "Treat CPUs as a revocable resource.")
-  static final Arg<Boolean> ENABLE_REVOCABLE_CPUS = Arg.create(true);
+  @Parameter(names = "-enable_revocable_cpus",
+      description = "Treat CPUs as a revocable resource.",
+      arity = 1)
+  public boolean enableRevocableCpus = true;
 
-  @CmdLine(name = "enable_revocable_ram", help = "Treat RAM as a revocable resource.")
-  static final Arg<Boolean> ENABLE_REVOCABLE_RAM = Arg.create(false);
+  @Parameter(names = "-enable_revocable_ram",
+      description = "Treat RAM as a revocable resource.",
+      arity = 1)
+  public boolean enableRevocableRam = false;
 
   static final Supplier<Boolean> NOT_REVOCABLE = () -> false;
-
-  private ResourceSettings() {
-
-  }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java b/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java
index de43eaa..9891942 100644
--- a/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java
+++ b/src/main/java/org/apache/aurora/scheduler/resources/ResourceType.java
@@ -23,6 +23,7 @@ import com.google.common.collect.Maps;
 
 import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.gen.Resource._Fields;
+import org.apache.aurora.scheduler.config.CommandLine;
 import org.apache.aurora.scheduler.storage.entities.IResource;
 import org.apache.mesos.v1.Protos.Resource;
 import org.apache.thrift.TEnum;
@@ -37,8 +38,6 @@ import static org.apache.aurora.scheduler.resources.AuroraResourceConverter.STRI
 import static org.apache.aurora.scheduler.resources.MesosResourceConverter.RANGES;
 import static org.apache.aurora.scheduler.resources.MesosResourceConverter.SCALAR;
 import static org.apache.aurora.scheduler.resources.ResourceMapper.PORT_MAPPER;
-import static org.apache.aurora.scheduler.resources.ResourceSettings.ENABLE_REVOCABLE_CPUS;
-import static org.apache.aurora.scheduler.resources.ResourceSettings.ENABLE_REVOCABLE_RAM;
 import static org.apache.aurora.scheduler.resources.ResourceSettings.NOT_REVOCABLE;
 
 /**
@@ -46,6 +45,7 @@ import static org.apache.aurora.scheduler.resources.ResourceSettings.NOT_REVOCAB
  */
 @VisibleForTesting
 public enum ResourceType implements TEnum {
+
   /**
    * CPU resource.
    */
@@ -59,7 +59,8 @@ public enum ResourceType implements TEnum {
       "core(s)",
       16,
       false,
-      ENABLE_REVOCABLE_CPUS),
+          // TODO(wfarner): Figure out why checkstyle wants this indentation.
+          () -> CommandLine.legacyGetStaticOptions().resourceSettings.enableRevocableCpus),
 
   /**
    * RAM resource.
@@ -74,7 +75,7 @@ public enum ResourceType implements TEnum {
       "MB",
       Amount.of(24, GB).as(MB),
       false,
-      ENABLE_REVOCABLE_RAM),
+          () -> CommandLine.legacyGetStaticOptions().resourceSettings.enableRevocableRam),
 
   /**
    * DISK resource.
@@ -121,6 +122,10 @@ public enum ResourceType implements TEnum {
       false,
       NOT_REVOCABLE);
 
+  public static void initializeEmptyCliArgsForTest() {
+    CommandLine.initializeForTest();
+  }
+
   /**
    * Correspondent thrift {@link org.apache.aurora.gen.Resource} enum value.
    */

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/scheduling/RescheduleCalculator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/scheduling/RescheduleCalculator.java b/src/main/java/org/apache/aurora/scheduler/scheduling/RescheduleCalculator.java
index 7107027..c0e877d 100644
--- a/src/main/java/org/apache/aurora/scheduler/scheduling/RescheduleCalculator.java
+++ b/src/main/java/org/apache/aurora/scheduler/scheduling/RescheduleCalculator.java
@@ -27,12 +27,12 @@ import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
-import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.common.util.BackoffStrategy;
 import org.apache.aurora.common.util.Random;
 import org.apache.aurora.gen.ScheduleStatus;
 import org.apache.aurora.scheduler.base.Tasks;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.entities.IScheduledTask;
 import org.apache.aurora.scheduler.storage.entities.ITaskEvent;
@@ -115,13 +115,13 @@ public interface RescheduleCalculator {
     @VisibleForTesting
     public static class RescheduleCalculatorSettings {
       private final BackoffStrategy flappingTaskBackoff;
-      private final Amount<Long, Time> flappingTaskThreashold;
-      private final Amount<Integer, Time>  maxStartupRescheduleDelay;
+      private final TimeAmount flappingTaskThreashold;
+      private final TimeAmount  maxStartupRescheduleDelay;
 
       public RescheduleCalculatorSettings(
           BackoffStrategy flappingTaskBackoff,
-          Amount<Long, Time> flappingTaskThreashold,
-          Amount<Integer, Time> maxStartupRescheduleDelay) {
+          TimeAmount flappingTaskThreashold,
+          TimeAmount maxStartupRescheduleDelay) {
 
         this.flappingTaskBackoff = requireNonNull(flappingTaskBackoff);
         this.flappingTaskThreashold = requireNonNull(flappingTaskThreashold);

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/scheduling/SchedulingModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/scheduling/SchedulingModule.java b/src/main/java/org/apache/aurora/scheduler/scheduling/SchedulingModule.java
index 0415016..0796712 100644
--- a/src/main/java/org/apache/aurora/scheduler/scheduling/SchedulingModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/scheduling/SchedulingModule.java
@@ -15,18 +15,19 @@ package org.apache.aurora.scheduler.scheduling;
 
 import javax.inject.Singleton;
 
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.util.concurrent.RateLimiter;
 import com.google.inject.AbstractModule;
 import com.google.inject.PrivateModule;
 import com.google.inject.TypeLiteral;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
-import org.apache.aurora.common.args.constraints.Positive;
-import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.common.util.TruncatedBinaryBackoff;
 import org.apache.aurora.scheduler.base.TaskGroupKey;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
+import org.apache.aurora.scheduler.config.validators.PositiveAmount;
+import org.apache.aurora.scheduler.config.validators.PositiveNumber;
 import org.apache.aurora.scheduler.events.PubsubEventModule;
 import org.apache.aurora.scheduler.preemptor.BiCache;
 import org.apache.aurora.scheduler.scheduling.RescheduleCalculator.RescheduleCalculatorImpl;
@@ -38,62 +39,68 @@ import static org.apache.aurora.scheduler.SchedulerServicesModule.addSchedulerAc
  */
 public class SchedulingModule extends AbstractModule {
 
-  @CmdLine(name = "max_schedule_attempts_per_sec",
-      help = "Maximum number of scheduling attempts to make per second.")
-  private static final Arg<Double> MAX_SCHEDULE_ATTEMPTS_PER_SEC = Arg.create(40D);
-
-  @CmdLine(name = "flapping_task_threshold",
-      help = "A task that repeatedly runs for less than this time is considered to be flapping.")
-  private static final Arg<Amount<Long, Time>> FLAPPING_THRESHOLD =
-      Arg.create(Amount.of(5L, Time.MINUTES));
-
-  @CmdLine(name = "initial_flapping_task_delay",
-      help = "Initial amount of time to wait before attempting to schedule a flapping task.")
-  private static final Arg<Amount<Long, Time>> INITIAL_FLAPPING_DELAY =
-      Arg.create(Amount.of(30L, Time.SECONDS));
-
-  @CmdLine(name = "max_flapping_task_delay",
-      help = "Maximum delay between attempts to schedule a flapping task.")
-  private static final Arg<Amount<Long, Time>> MAX_FLAPPING_DELAY =
-      Arg.create(Amount.of(5L, Time.MINUTES));
-
-  @CmdLine(name = "max_reschedule_task_delay_on_startup",
-      help = "Upper bound of random delay for pending task rescheduling on scheduler startup.")
-  private static final Arg<Amount<Integer, Time>> MAX_RESCHEDULING_DELAY =
-      Arg.create(Amount.of(30, Time.SECONDS));
-
-  @Positive
-  @CmdLine(name = "first_schedule_delay",
-      help = "Initial amount of time to wait before first attempting to schedule a PENDING task.")
-  private static final Arg<Amount<Long, Time>> FIRST_SCHEDULE_DELAY =
-      Arg.create(Amount.of(1L, Time.MILLISECONDS));
-
-  @Positive
-  @CmdLine(name = "initial_schedule_penalty",
-      help = "Initial amount of time to wait before attempting to schedule a task that has failed"
-          + " to schedule.")
-  private static final Arg<Amount<Long, Time>> INITIAL_SCHEDULE_PENALTY =
-      Arg.create(Amount.of(1L, Time.SECONDS));
-
-  @CmdLine(name = "max_schedule_penalty",
-      help = "Maximum delay between attempts to schedule a PENDING tasks.")
-  private static final Arg<Amount<Long, Time>> MAX_SCHEDULE_PENALTY =
-      Arg.create(Amount.of(1L, Time.MINUTES));
-
-  @CmdLine(name = "offer_reservation_duration", help = "Time to reserve a agent's offers while "
-      + "trying to satisfy a task preempting another.")
-  private static final Arg<Amount<Long, Time>> RESERVATION_DURATION =
-      Arg.create(Amount.of(3L, Time.MINUTES));
-
-  @Positive
-  @CmdLine(name = "scheduling_max_batch_size",
-      help = "The maximum number of scheduling attempts that can be processed in a batch.")
-  private static final Arg<Integer> SCHEDULING_MAX_BATCH_SIZE = Arg.create(3);
-
-  @Positive
-  @CmdLine(name = "max_tasks_per_schedule_attempt",
-      help = "The maximum number of tasks to pick in a single scheduling attempt.")
-  private static final Arg<Integer> MAX_TASKS_PER_SCHEDULE_ATTEMPT = Arg.create(5);
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-max_schedule_attempts_per_sec",
+        description = "Maximum number of scheduling attempts to make per second.")
+    public double maxScheduleAttemptsPerSec = 40D;
+
+    @Parameter(names = "-flapping_task_threshold",
+        description =
+            "A task that repeatedly runs for less than this time is considered to be flapping.")
+    public TimeAmount flappingThreshold = new TimeAmount(5, Time.MINUTES);
+
+    @Parameter(names = "-initial_flapping_task_delay",
+        description =
+            "Initial amount of time to wait before attempting to schedule a flapping task.")
+    public TimeAmount initialFlappingDelay = new TimeAmount(30, Time.SECONDS);
+
+    @Parameter(names = "-max_flapping_task_delay",
+        description = "Maximum delay between attempts to schedule a flapping task.")
+    public TimeAmount maxFlappingDelay = new TimeAmount(5, Time.MINUTES);
+
+    @Parameter(names = "-max_reschedule_task_delay_on_startup",
+        description =
+            "Upper bound of random delay for pending task rescheduling on scheduler startup.")
+    public TimeAmount maxReschedulingDelay = new TimeAmount(30, Time.SECONDS);
+
+    @Parameter(names = "-first_schedule_delay",
+        validateValueWith = PositiveAmount.class,
+        description =
+            "Initial amount of time to wait before first attempting to schedule a PENDING task.")
+    public TimeAmount firstScheduleDelay = new TimeAmount(1, Time.MILLISECONDS);
+
+    @Parameter(names = "-initial_schedule_penalty",
+        validateValueWith = PositiveAmount.class,
+        description = "Initial amount of time to wait before attempting to schedule a task that "
+            + "has failed to schedule.")
+    public TimeAmount initialSchedulePenalty = new TimeAmount(1, Time.SECONDS);
+
+    @Parameter(names = "-max_schedule_penalty",
+        description = "Maximum delay between attempts to schedule a PENDING tasks.")
+    public TimeAmount maxSchedulePenalty = new TimeAmount(1, Time.MINUTES);
+
+    @Parameter(names = "-offer_reservation_duration",
+        description = "Time to reserve a agent's offers while "
+            + "trying to satisfy a task preempting another.")
+    public TimeAmount reservationDuration = new TimeAmount(3, Time.MINUTES);
+
+    @Parameter(names = "-scheduling_max_batch_size",
+        validateValueWith = PositiveNumber.class,
+        description = "The maximum number of scheduling attempts that can be processed in a batch.")
+    public int schedulingMaxBatchSize = 3;
+
+    @Parameter(names = "-max_tasks_per_schedule_attempt",
+        validateValueWith = PositiveNumber.class,
+        description = "The maximum number of tasks to pick in a single scheduling attempt.")
+    public int maxTasksPerScheduleAttempt = 5;
+  }
+
+  private final Options options;
+
+  public SchedulingModule(Options options) {
+    this.options = options;
+  }
 
   @Override
   protected void configure() {
@@ -101,18 +108,16 @@ public class SchedulingModule extends AbstractModule {
       @Override
       protected void configure() {
         bind(TaskGroups.TaskGroupsSettings.class).toInstance(new TaskGroups.TaskGroupsSettings(
-            FIRST_SCHEDULE_DELAY.get(),
-            new TruncatedBinaryBackoff(
-                INITIAL_SCHEDULE_PENALTY.get(),
-                MAX_SCHEDULE_PENALTY.get()),
-            RateLimiter.create(MAX_SCHEDULE_ATTEMPTS_PER_SEC.get()),
-            MAX_TASKS_PER_SCHEDULE_ATTEMPT.get()));
+            options.firstScheduleDelay,
+            new TruncatedBinaryBackoff(options.initialSchedulePenalty, options.maxSchedulePenalty),
+            RateLimiter.create(options.maxScheduleAttemptsPerSec),
+            options.maxTasksPerScheduleAttempt));
 
         bind(RescheduleCalculatorImpl.RescheduleCalculatorSettings.class)
             .toInstance(new RescheduleCalculatorImpl.RescheduleCalculatorSettings(
-                new TruncatedBinaryBackoff(INITIAL_FLAPPING_DELAY.get(), MAX_FLAPPING_DELAY.get()),
-                FLAPPING_THRESHOLD.get(),
-                MAX_RESCHEDULING_DELAY.get()));
+                new TruncatedBinaryBackoff(options.initialFlappingDelay, options.maxFlappingDelay),
+                options.flappingThreshold,
+                options.maxReschedulingDelay));
 
         bind(RescheduleCalculator.class).to(RescheduleCalculatorImpl.class).in(Singleton.class);
         expose(RescheduleCalculator.class);
@@ -124,7 +129,7 @@ public class SchedulingModule extends AbstractModule {
 
     bind(new TypeLiteral<Integer>() { })
         .annotatedWith(TaskGroups.SchedulingMaxBatchSize.class)
-        .toInstance(SCHEDULING_MAX_BATCH_SIZE.get());
+        .toInstance(options.schedulingMaxBatchSize);
     bind(TaskGroups.TaskGroupBatchWorker.class).in(Singleton.class);
     addSchedulerActiveServiceBinding(binder()).to(TaskGroups.TaskGroupBatchWorker.class);
 
@@ -133,7 +138,7 @@ public class SchedulingModule extends AbstractModule {
       protected void configure() {
         bind(new TypeLiteral<BiCache<String, TaskGroupKey>>() { }).in(Singleton.class);
         bind(BiCache.BiCacheSettings.class).toInstance(
-            new BiCache.BiCacheSettings(RESERVATION_DURATION.get(), "reservation"));
+            new BiCache.BiCacheSettings(options.reservationDuration, "reservation"));
         bind(TaskScheduler.class).to(TaskScheduler.TaskSchedulerImpl.class);
         bind(TaskScheduler.TaskSchedulerImpl.class).in(Singleton.class);
         expose(TaskScheduler.class);

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/sla/MetricCalculator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/sla/MetricCalculator.java b/src/main/java/org/apache/aurora/scheduler/sla/MetricCalculator.java
index 9a56cda..52a7b63 100644
--- a/src/main/java/org/apache/aurora/scheduler/sla/MetricCalculator.java
+++ b/src/main/java/org/apache/aurora/scheduler/sla/MetricCalculator.java
@@ -64,7 +64,7 @@ import static org.apache.aurora.scheduler.sla.SlaGroup.GroupType.RESOURCE_RAM;
 /**
  * Responsible for calculating and exporting SLA metrics.
  */
-class MetricCalculator implements Runnable {
+public class MetricCalculator implements Runnable {
 
   @VisibleForTesting
   static final String NAME_QUALIFIER_PROD = "";
@@ -75,7 +75,7 @@ class MetricCalculator implements Runnable {
   /**
    * Pre-configured categories of metrics.
    */
-  enum MetricCategory {
+  public enum MetricCategory {
 
     JOB_UPTIMES(ImmutableMultimap.<AlgorithmType, GroupType>builder()
         .put(JOB_UPTIME_50, JOB)

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/sla/SlaModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/sla/SlaModule.java b/src/main/java/org/apache/aurora/scheduler/sla/SlaModule.java
index d569241..7c8d2df 100644
--- a/src/main/java/org/apache/aurora/scheduler/sla/SlaModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/sla/SlaModule.java
@@ -15,26 +15,27 @@ package org.apache.aurora.scheduler.sla;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
-import java.util.Set;
+import java.util.List;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
 import javax.inject.Qualifier;
 
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.util.concurrent.AbstractIdleService;
 import com.google.inject.AbstractModule;
 import com.google.inject.Singleton;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
-import org.apache.aurora.common.args.constraints.Positive;
-import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.scheduler.SchedulerServicesModule;
 import org.apache.aurora.scheduler.base.AsyncUtil;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
+import org.apache.aurora.scheduler.config.validators.PositiveAmount;
 import org.apache.aurora.scheduler.sla.MetricCalculator.MetricCalculatorSettings;
 import org.apache.aurora.scheduler.sla.MetricCalculator.MetricCategory;
 import org.slf4j.Logger;
@@ -57,52 +58,41 @@ public class SlaModule extends AbstractModule {
 
   private static final Logger LOG = LoggerFactory.getLogger(SlaModule.class);
 
-  @Positive
-  @CmdLine(name = "sla_stat_refresh_interval", help = "The SLA stat refresh interval.")
-  private static final Arg<Amount<Long, Time>> SLA_REFRESH_INTERVAL =
-      Arg.create(Amount.of(1L, Time.MINUTES));
-
-  @CmdLine(name = "sla_prod_metrics",
-      help = "Metric categories collected for production tasks.")
-  private static final Arg<Set<MetricCategory>> SLA_PROD_METRICS =
-      Arg.<Set<MetricCategory>>create(ImmutableSet.of(JOB_UPTIMES, PLATFORM_UPTIME, MEDIANS));
-
-  @CmdLine(name = "sla_non_prod_metrics",
-      help = "Metric categories collected for non production tasks.")
-  private static final Arg<Set<MetricCategory>> SLA_NON_PROD_METRICS =
-      Arg.<Set<MetricCategory>>create(ImmutableSet.of());
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-sla_stat_refresh_interval",
+        validateValueWith = PositiveAmount.class,
+        description = "The SLA stat refresh interval.")
+    public TimeAmount slaRefreshInterval = new TimeAmount(1, Time.MINUTES);
+
+    @Parameter(names = "-sla_prod_metrics",
+        description = "Metric categories collected for production tasks.")
+    public List<MetricCategory> slaProdMetrics =
+        ImmutableList.of(JOB_UPTIMES, PLATFORM_UPTIME, MEDIANS);
+
+    @Parameter(names = "-sla_non_prod_metrics",
+        description = "Metric categories collected for non production tasks.")
+    public List<MetricCategory> slaNonProdMetrics = ImmutableList.of();
+  }
 
   @VisibleForTesting
   @Qualifier
   @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)
   @interface SlaExecutor { }
 
-  private final Amount<Long, Time> refreshInterval;
-  private final Set<MetricCategory> prodMetrics;
-  private final Set<MetricCategory> nonProdMetrics;
-
-  @VisibleForTesting
-  SlaModule(
-      Amount<Long, Time> refreshInterval,
-      Set<MetricCategory> prodMetrics,
-      Set<MetricCategory> nonProdMetrics) {
-
-    this.refreshInterval = refreshInterval;
-    this.prodMetrics = prodMetrics;
-    this.nonProdMetrics = nonProdMetrics;
-  }
+  private final Options options;
 
-  public SlaModule() {
-    this(SLA_REFRESH_INTERVAL.get(), SLA_PROD_METRICS.get(), SLA_NON_PROD_METRICS.get());
+  public SlaModule(Options options) {
+    this.options = options;
   }
 
   @Override
   protected void configure() {
     bind(MetricCalculatorSettings.class)
         .toInstance(new MetricCalculatorSettings(
-            refreshInterval.as(Time.MILLISECONDS),
-            prodMetrics,
-            nonProdMetrics));
+            options.slaRefreshInterval.as(Time.MILLISECONDS),
+            ImmutableSet.copyOf(options.slaProdMetrics),
+            ImmutableSet.copyOf(options.slaNonProdMetrics)));
 
     bind(MetricCalculator.class).in(Singleton.class);
     bind(ScheduledExecutorService.class)

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/state/StateModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/state/StateModule.java b/src/main/java/org/apache/aurora/scheduler/state/StateModule.java
index 77a37b8..d72f055 100644
--- a/src/main/java/org/apache/aurora/scheduler/state/StateModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/state/StateModule.java
@@ -13,49 +13,48 @@
  */
 package org.apache.aurora.scheduler.state;
 
-import java.util.Set;
+import java.util.List;
+
 import javax.inject.Singleton;
 
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Module;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
 import org.apache.aurora.scheduler.app.MoreModules;
+import org.apache.aurora.scheduler.config.CliOptions;
 import org.apache.aurora.scheduler.events.PubsubEventModule;
 import org.apache.aurora.scheduler.mesos.MesosTaskFactory;
 import org.apache.aurora.scheduler.mesos.MesosTaskFactory.MesosTaskFactoryImpl;
 import org.apache.aurora.scheduler.state.MaintenanceController.MaintenanceControllerImpl;
 import org.apache.aurora.scheduler.state.UUIDGenerator.UUIDGeneratorImpl;
 
-import static java.util.Objects.requireNonNull;
-
 /**
  * Binding module for scheduling logic and higher-level state management.
  */
 public class StateModule extends AbstractModule {
 
-  @CmdLine(name = "task_assigner_modules",
-      help = "Guice modules for customizing task assignment.")
-  private static final Arg<Set<Module>> TASK_ASSIGNER_MODULES = Arg.create(
-      ImmutableSet.of(MoreModules.lazilyInstantiated(FirstFitTaskAssignerModule.class)));
-
-  private final Set<Module> assignerModules;
-
-  public StateModule() {
-    this(TASK_ASSIGNER_MODULES.get());
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-task_assigner_modules",
+        description = "Guice modules for customizing task assignment.")
+    @SuppressWarnings("rawtypes")
+    public List<Class> taskAssignerModules = ImmutableList.of(FirstFitTaskAssignerModule.class);
   }
 
-  private StateModule(Set<Module> assignerModules) {
-    this.assignerModules = requireNonNull(assignerModules);
+  private final CliOptions options;
+
+  public StateModule(CliOptions options) {
+    this.options = options;
   }
 
   @Override
   protected void configure() {
-    for (Module module: assignerModules) {
+    for (Module module : MoreModules.instantiateAll(options.state.taskAssignerModules, options)) {
       install(module);
     }
     bind(MesosTaskFactory.class).to(MesosTaskFactoryImpl.class);

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/stats/AsyncStatsModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/stats/AsyncStatsModule.java b/src/main/java/org/apache/aurora/scheduler/stats/AsyncStatsModule.java
index 40451e9..6033c01 100644
--- a/src/main/java/org/apache/aurora/scheduler/stats/AsyncStatsModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/stats/AsyncStatsModule.java
@@ -16,19 +16,20 @@ package org.apache.aurora.scheduler.stats;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.AbstractScheduledService;
 import com.google.common.util.concurrent.AbstractScheduledService.Scheduler;
 import com.google.inject.AbstractModule;
 import com.google.inject.PrivateModule;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
 import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.scheduler.HostOffer;
 import org.apache.aurora.scheduler.SchedulerServicesModule;
 import org.apache.aurora.scheduler.base.Conversions;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
 import org.apache.aurora.scheduler.offers.OfferManager;
 import org.apache.aurora.scheduler.resources.ResourceBag;
 import org.apache.aurora.scheduler.stats.SlotSizeCounter.MachineResource;
@@ -46,15 +47,23 @@ import static org.apache.aurora.scheduler.resources.ResourceManager.getRevocable
  * Module to configure export of cluster-wide resource allocation and consumption statistics.
  */
 public class AsyncStatsModule extends AbstractModule {
-  @CmdLine(name = "async_task_stat_update_interval",
-      help = "Interval on which to try to update resource consumption stats.")
-  private static final Arg<Amount<Long, Time>> TASK_STAT_INTERVAL =
-      Arg.create(Amount.of(1L, Time.HOURS));
 
-  @CmdLine(name = "async_slot_stat_update_interval",
-      help = "Interval on which to try to update open slot stats.")
-  private static final Arg<Amount<Long, Time>> SLOT_STAT_INTERVAL =
-      Arg.create(Amount.of(1L, Time.MINUTES));
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-async_task_stat_update_interval",
+        description = "Interval on which to try to update resource consumption stats.")
+    public TimeAmount taskStatInterval = new TimeAmount(1, Time.HOURS);
+
+    @Parameter(names = "-async_slot_stat_update_interval",
+        description = "Interval on which to try to update open slot stats.")
+    public TimeAmount slotStatInterval = new TimeAmount(1, Time.MINUTES);
+  }
+
+  private final Options options;
+
+  public AsyncStatsModule(Options options) {
+    this.options = options;
+  }
 
   @Override
   protected void configure() {
@@ -67,11 +76,12 @@ public class AsyncStatsModule extends AbstractModule {
       @Override
       protected void configure() {
         bind(TaskStatUpdaterService.class).in(Singleton.class);
+        Amount<Long, Time> taskStatInterval = options.taskStatInterval;
         bind(Scheduler.class).toInstance(
             Scheduler.newFixedRateSchedule(
-                TASK_STAT_INTERVAL.get().getValue(),
-                TASK_STAT_INTERVAL.get().getValue(),
-                TASK_STAT_INTERVAL.get().getUnit().getTimeUnit()));
+                taskStatInterval.getValue(),
+                taskStatInterval.getValue(),
+                taskStatInterval.getUnit().getTimeUnit()));
         expose(TaskStatUpdaterService.class);
       }
     });
@@ -82,11 +92,12 @@ public class AsyncStatsModule extends AbstractModule {
       @Override
       protected void configure() {
         bind(SlotSizeCounterService.class).in(Singleton.class);
+        Amount<Long, Time> slotStatInterval = options.slotStatInterval;
         bind(Scheduler.class).toInstance(
             Scheduler.newFixedRateSchedule(
-                SLOT_STAT_INTERVAL.get().getValue(),
-                SLOT_STAT_INTERVAL.get().getValue(),
-                SLOT_STAT_INTERVAL.get().getUnit().getTimeUnit()));
+                slotStatInterval.getValue(),
+                slotStatInterval.getValue(),
+                slotStatInterval.getUnit().getTimeUnit()));
         expose(SlotSizeCounterService.class);
       }
     });

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/stats/StatsModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/stats/StatsModule.java b/src/main/java/org/apache/aurora/scheduler/stats/StatsModule.java
index 4767ef1..24816ac 100644
--- a/src/main/java/org/apache/aurora/scheduler/stats/StatsModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/stats/StatsModule.java
@@ -13,6 +13,8 @@
  */
 package org.apache.aurora.scheduler.stats;
 
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.base.Supplier;
 import com.google.inject.AbstractModule;
 import com.google.inject.Singleton;
@@ -20,8 +22,6 @@ import com.google.inject.TypeLiteral;
 import com.google.inject.name.Names;
 
 import org.apache.aurora.common.application.ShutdownRegistry;
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
 import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.common.stats.Stat;
@@ -30,20 +30,29 @@ import org.apache.aurora.common.stats.Stats;
 import org.apache.aurora.common.stats.TimeSeriesRepository;
 import org.apache.aurora.common.stats.TimeSeriesRepositoryImpl;
 import org.apache.aurora.scheduler.SchedulerServicesModule;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
 
 /**
  * Binding module for injections related to the in-process stats system.
  */
 public class StatsModule extends AbstractModule {
 
-  @CmdLine(name = "stat_sampling_interval", help = "Statistic value sampling interval.")
-  private static final Arg<Amount<Long, Time>> SAMPLING_INTERVAL =
-      Arg.create(Amount.of(1L, Time.SECONDS));
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-stat_sampling_interval",
+        description = "Statistic value sampling interval.")
+    public TimeAmount samplingInterval = new TimeAmount(1, Time.SECONDS);
 
-  @CmdLine(name = "stat_retention_period",
-      help = "Time for a stat to be retained in memory before expiring.")
-  private static final Arg<Amount<Long, Time>> RETENTION_PERIOD =
-      Arg.create(Amount.of(1L, Time.HOURS));
+    @Parameter(names = "-stat_retention_period",
+        description = "Time for a stat to be retained in memory before expiring.")
+    public TimeAmount retentionPeriod = new TimeAmount(1, Time.HOURS);
+  }
+
+  private final Options options;
+
+  public StatsModule(Options options) {
+    this.options = options;
+  }
 
   @Override
   protected void configure() {
@@ -53,10 +62,10 @@ public class StatsModule extends AbstractModule {
     bind(StatRegistry.class).toInstance(Stats.STAT_REGISTRY);
     bind(new TypeLiteral<Amount<Long, Time>>() { })
         .annotatedWith(Names.named(TimeSeriesRepositoryImpl.SAMPLE_RETENTION_PERIOD))
-        .toInstance(RETENTION_PERIOD.get());
+        .toInstance(options.retentionPeriod);
     bind(new TypeLiteral<Amount<Long, Time>>() { })
         .annotatedWith(Names.named(TimeSeriesRepositoryImpl.SAMPLE_PERIOD))
-        .toInstance(SAMPLING_INTERVAL.get());
+        .toInstance(options.samplingInterval);
     bind(TimeSeriesRepository.class).to(TimeSeriesRepositoryImpl.class);
     bind(TimeSeriesRepositoryImpl.class).in(Singleton.class);
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/storage/backup/BackupModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/backup/BackupModule.java b/src/main/java/org/apache/aurora/scheduler/storage/backup/BackupModule.java
index cded40b..7eaae89 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/backup/BackupModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/backup/BackupModule.java
@@ -19,21 +19,19 @@ import java.util.concurrent.Executor;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 
-import com.google.common.annotations.VisibleForTesting;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.base.Function;
 import com.google.inject.PrivateModule;
 import com.google.inject.Provides;
 import com.google.inject.TypeLiteral;
 
 import org.apache.aurora.common.application.Lifecycle;
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
-import org.apache.aurora.common.args.constraints.NotNull;
 import org.apache.aurora.common.base.Command;
-import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.gen.storage.Snapshot;
 import org.apache.aurora.scheduler.base.AsyncUtil;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
 import org.apache.aurora.scheduler.storage.SnapshotStore;
 import org.apache.aurora.scheduler.storage.backup.Recovery.RecoveryImpl;
 import org.apache.aurora.scheduler.storage.backup.StorageBackup.StorageBackupImpl;
@@ -51,41 +49,28 @@ import static java.util.Objects.requireNonNull;
 public class BackupModule extends PrivateModule {
   private static final Logger LOG = LoggerFactory.getLogger(BackupModule.class);
 
-  @CmdLine(name = "backup_interval", help = "Minimum interval on which to write a storage backup.")
-  private static final Arg<Amount<Long, Time>> BACKUP_INTERVAL =
-      Arg.create(Amount.of(1L, Time.HOURS));
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-backup_interval",
+        description = "Minimum interval on which to write a storage backup.")
+    public TimeAmount backupInterval = new TimeAmount(1, Time.HOURS);
 
-  @CmdLine(name = "max_saved_backups",
-      help = "Maximum number of backups to retain before deleting the oldest backups.")
-  private static final Arg<Integer> MAX_SAVED_BACKUPS = Arg.create(48);
+    @Parameter(names = "-max_saved_backups",
+        description = "Maximum number of backups to retain before deleting the oldest backups.")
+    public int maxSavedBackups = 48;
 
-  @NotNull
-  @CmdLine(name = "backup_dir",
-      help = "Directory to store backups under. Will be created if it does not exist.")
-  private static final Arg<File> BACKUP_DIR = Arg.create();
+    @Parameter(names = "-backup_dir",
+        required = true,
+        description = "Directory to store backups under. Will be created if it does not exist.")
+    public File backupDir;
+  }
 
+  private final Options options;
   private final Class<? extends SnapshotStore<Snapshot>> snapshotStore;
-  private final File unvalidatedBackupDir;
-
-  /**
-   * Creates a new backup module.
-   *
-   * @param snapshotStore Snapshot store implementation class.
-   */
-  public BackupModule(Class<? extends SnapshotStore<Snapshot>> snapshotStore) {
-    this(BACKUP_DIR.get(), snapshotStore);
-  }
 
-  /**
-   * Creates a new backup module using a given backupDir instead of a flagged one.
-   *
-   * @param backupDir Directory to write backups to.
-   * @param snapshotStore Snapshot store implementation class.
-   */
-  @VisibleForTesting
-  public BackupModule(File backupDir, Class<? extends SnapshotStore<Snapshot>> snapshotStore) {
-    this.unvalidatedBackupDir = requireNonNull(backupDir);
-    this.snapshotStore = requireNonNull(snapshotStore);
+  public BackupModule(Options options, Class<? extends SnapshotStore<Snapshot>> snapshotStore) {
+    this.options = options;
+    this.snapshotStore = snapshotStore;
   }
 
   @Override
@@ -126,25 +111,25 @@ public class BackupModule extends PrivateModule {
 
   @Provides
   File provideBackupDir() {
-    if (!unvalidatedBackupDir.exists()) {
-      if (unvalidatedBackupDir.mkdirs()) {
-        LOG.info("Created backup dir " + unvalidatedBackupDir.getPath() + ".");
+    if (!options.backupDir.exists()) {
+      if (options.backupDir.mkdirs()) {
+        LOG.info("Created backup dir " + options.backupDir.getPath() + ".");
       } else {
         throw new IllegalArgumentException(
-            "Unable to create backup dir " + unvalidatedBackupDir.getPath() + ".");
+            "Unable to create backup dir " + options.backupDir.getPath() + ".");
       }
     }
 
-    if (!unvalidatedBackupDir.canWrite()) {
+    if (!options.backupDir.canWrite()) {
       throw new IllegalArgumentException(
-          "Backup dir " + unvalidatedBackupDir.getPath() + " is not writable.");
+          "Backup dir " + options.backupDir.getPath() + " is not writable.");
     }
 
-    return unvalidatedBackupDir;
+    return options.backupDir;
   }
 
   @Provides
   BackupConfig provideBackupConfig(File backupDir) {
-    return new BackupConfig(backupDir, MAX_SAVED_BACKUPS.get(), BACKUP_INTERVAL.get());
+    return new BackupConfig(backupDir, options.maxSavedBackups, options.backupInterval);
   }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java b/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
index 0a2516e..fb3dadb 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbModule.java
@@ -19,6 +19,8 @@ import java.util.UUID;
 
 import javax.inject.Singleton;
 
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
@@ -32,15 +34,13 @@ import com.google.inject.PrivateModule;
 import com.google.inject.TypeLiteral;
 import com.google.inject.util.Modules;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
-import org.apache.aurora.common.args.constraints.Positive;
 import org.apache.aurora.common.inject.Bindings.KeyFactory;
 import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.scheduler.SchedulerServicesModule;
 import org.apache.aurora.scheduler.async.AsyncModule.AsyncExecutor;
 import org.apache.aurora.scheduler.async.GatedWorkQueue;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
 import org.apache.aurora.scheduler.storage.AttributeStore;
 import org.apache.aurora.scheduler.storage.CronJobStore;
 import org.apache.aurora.scheduler.storage.JobUpdateStore;
@@ -69,39 +69,39 @@ import static com.google.inject.name.Names.bindProperties;
  */
 public final class DbModule extends PrivateModule {
 
-  @CmdLine(name = "use_beta_db_task_store",
-      help = "Whether to use the experimental database-backed task store.")
-  public static final Arg<Boolean> USE_DB_TASK_STORE = Arg.create(false);
-
-  @CmdLine(name = "enable_db_metrics",
-      help = "Whether to use MyBatis interceptor to measure the timing of intercepted Statements.")
-  private static final Arg<Boolean> ENABLE_DB_METRICS = Arg.create(true);
-
-  @CmdLine(name = "slow_query_log_threshold",
-      help = "Log all queries that take at least this long to execute.")
-  private static final Arg<Amount<Long, Time>> SLOW_QUERY_LOG_THRESHOLD =
-      Arg.create(Amount.of(25L, Time.MILLISECONDS));
-
-  @CmdLine(name = "db_row_gc_interval",
-      help = "Interval on which to scan the database for unused row references.")
-  private static final Arg<Amount<Long, Time>> DB_ROW_GC_INTERVAL =
-      Arg.create(Amount.of(2L, Time.HOURS));
-
-  // http://h2database.com/html/grammar.html#set_lock_timeout
-  @CmdLine(name = "db_lock_timeout", help = "H2 table lock timeout")
-  private static final Arg<Amount<Long, Time>> H2_LOCK_TIMEOUT =
-      Arg.create(Amount.of(1L, Time.MINUTES));
-
-  // Flags to configure the PooledDataSource from mybatis.
-  @Positive
-  @CmdLine(name = "db_max_active_connection_count",
-      help = "Max number of connections to use with database via MyBatis")
-  private static final Arg<Integer> MYBATIS_MAX_ACTIVE_CONNECTION_COUNT = Arg.create();
-
-  @Positive
-  @CmdLine(name = "db_max_idle_connection_count",
-      help = "Max number of idle connections to the database via MyBatis")
-  private static final Arg<Integer> MYBATIS_MAX_IDLE_CONNECTION_COUNT = Arg.create();
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-use_beta_db_task_store",
+        description = "Whether to use the experimental database-backed task store.",
+        arity = 1)
+    public boolean useDbTaskStore = false;
+
+    @Parameter(names = "-enable_db_metrics",
+        description =
+            "Whether to use MyBatis interceptor to measure the timing of intercepted Statements.",
+        arity = 1)
+    public boolean enableDbMetrics = true;
+
+    @Parameter(names = "-slow_query_log_threshold",
+        description = "Log all queries that take at least this long to execute.")
+    public TimeAmount slowQueryLogThreshold = new TimeAmount(25, Time.MILLISECONDS);
+
+    @Parameter(names = "-db_row_gc_interval",
+        description = "Interval on which to scan the database for unused row references.")
+    public TimeAmount dbRowGcInterval = new TimeAmount(2, Time.HOURS);
+
+    // http://h2database.com/html/grammar.html#set_lock_timeout
+    @Parameter(names = "-db_lock_timeout", description = "H2 table lock timeout")
+    public TimeAmount h2LockTimeout = new TimeAmount(1, Time.MINUTES);
+
+    @Parameter(names = "-db_max_active_connection_count",
+        description = "Max number of connections to use with database via MyBatis")
+    public int mybatisMaxActiveConnectionCount = -1;
+
+    @Parameter(names = "-db_max_idle_connection_count",
+        description = "Max number of idle connections to the database via MyBatis")
+    public int mybatisMaxIdleConnectionCount = -1;
+  }
 
   private static final Set<Class<?>> MAPPER_CLASSES = ImmutableSet.<Class<?>>builder()
       .add(AttributeMapper.class)
@@ -119,16 +119,19 @@ public final class DbModule extends PrivateModule {
       .add(TaskMapper.class)
       .build();
 
+  private final Options options;
   private final KeyFactory keyFactory;
   private final Module taskStoresModule;
   private final String jdbcSchema;
 
   private DbModule(
+      Options options,
       KeyFactory keyFactory,
       Module taskStoresModule,
       String dbName,
       Map<String, String> jdbcUriArgs) {
 
+    this.options = requireNonNull(options);
     this.keyFactory = requireNonNull(keyFactory);
     this.taskStoresModule = requireNonNull(taskStoresModule);
 
@@ -143,7 +146,7 @@ public final class DbModule extends PrivateModule {
         // Enable Query Statistics
         .put("QUERY_STATISTICS", "TRUE")
         // Configure the lock timeout
-        .put("LOCK_TIMEOUT", H2_LOCK_TIMEOUT.get().as(Time.MILLISECONDS).toString())
+        .put("LOCK_TIMEOUT", options.h2LockTimeout.as(Time.MILLISECONDS).toString())
         .build();
     this.jdbcSchema = dbName + ";" + Joiner.on(";").withKeyValueSeparator("=").join(args);
   }
@@ -155,19 +158,23 @@ public final class DbModule extends PrivateModule {
    * @param keyFactory Binding scope for the storage system.
    * @return A new database module for production.
    */
-  public static Module productionModule(KeyFactory keyFactory) {
+  public static Module productionModule(KeyFactory keyFactory, DbModule.Options options) {
     return new DbModule(
+        options,
         keyFactory,
-        getTaskStoreModule(keyFactory),
+        getTaskStoreModule(options, keyFactory),
         "aurora",
         ImmutableMap.of("DB_CLOSE_DELAY", "-1"));
   }
 
   @VisibleForTesting
   public static Module testModule(KeyFactory keyFactory, Optional<Module> taskStoreModule) {
+    DbModule.Options options = new DbModule.Options();
     return new DbModule(
+        options,
         keyFactory,
-        taskStoreModule.isPresent() ? taskStoreModule.get() : getTaskStoreModule(keyFactory),
+        taskStoreModule.isPresent()
+            ? taskStoreModule.get() : getTaskStoreModule(options, keyFactory),
         "testdb-" + UUID.randomUUID().toString(),
         // A non-zero close delay is used here to avoid eager database cleanup in tests that
         // make use of multiple threads.  Since all test databases are separately scoped by the
@@ -232,10 +239,10 @@ public final class DbModule extends PrivateModule {
         Optional.of(new TaskStoreModule(KeyFactory.PLAIN)));
   }
 
-  private static Module getTaskStoreModule(KeyFactory keyFactory) {
-    return USE_DB_TASK_STORE.get()
+  private static Module getTaskStoreModule(Options options, KeyFactory keyFactory) {
+    return options.useDbTaskStore
         ? new TaskStoreModule(keyFactory)
-        : new InMemStoresModule(keyFactory);
+        : new InMemStoresModule(options, keyFactory);
   }
 
   private <T> void bindStore(Class<T> binding, Class<? extends T> impl) {
@@ -251,7 +258,7 @@ public final class DbModule extends PrivateModule {
     install(new MyBatisModule() {
       @Override
       protected void initialize() {
-        if (ENABLE_DB_METRICS.get()) {
+        if (options.enableDbMetrics) {
           addInterceptorClass(InstrumentingInterceptor.class);
         }
 
@@ -273,20 +280,21 @@ public final class DbModule extends PrivateModule {
 
         addTypeHandlersClasses(TypeHandlers.getAll());
 
-        bind(new TypeLiteral<Amount<Long, Time>>() { }).toInstance(SLOW_QUERY_LOG_THRESHOLD.get());
+        bind(new TypeLiteral<Amount<Long, Time>>() { })
+            .toInstance(options.slowQueryLogThreshold);
 
         // Enable a ping query which will prevent the use of invalid connections in the
         // connection pool.
         bindProperties(binder(), ImmutableMap.of("mybatis.pooled.pingEnabled", "true"));
         bindProperties(binder(), ImmutableMap.of("mybatis.pooled.pingQuery", "SELECT 1;"));
 
-        if (MYBATIS_MAX_ACTIVE_CONNECTION_COUNT.hasAppliedValue()) {
-          String val = MYBATIS_MAX_ACTIVE_CONNECTION_COUNT.get().toString();
+        if (options.mybatisMaxActiveConnectionCount > 0) {
+          String val = String.valueOf(options.mybatisMaxActiveConnectionCount);
           bindProperties(binder(), ImmutableMap.of("mybatis.pooled.maximumActiveConnections", val));
         }
 
-        if (MYBATIS_MAX_IDLE_CONNECTION_COUNT.hasAppliedValue()) {
-          String val = MYBATIS_MAX_IDLE_CONNECTION_COUNT.get().toString();
+        if (options.mybatisMaxIdleConnectionCount > 0) {
+          String val = String.valueOf(options.mybatisMaxIdleConnectionCount);
           bindProperties(binder(), ImmutableMap.of("mybatis.pooled.maximumIdleConnections", val));
         }
 
@@ -359,6 +367,13 @@ public final class DbModule extends PrivateModule {
    * Module that sets up a periodic database garbage-collection routine.
    */
   public static class GarbageCollectorModule extends AbstractModule {
+
+    private final Options options;
+
+    public GarbageCollectorModule(Options options) {
+      this.options = options;
+    }
+
     @Override
     protected void configure() {
       install(new PrivateModule() {
@@ -368,8 +383,8 @@ public final class DbModule extends PrivateModule {
           bind(AbstractScheduledService.Scheduler.class).toInstance(
               AbstractScheduledService.Scheduler.newFixedRateSchedule(
                   0L,
-                  DB_ROW_GC_INTERVAL.get().getValue(),
-                  DB_ROW_GC_INTERVAL.get().getUnit().getTimeUnit()));
+                  options.dbRowGcInterval.getValue(),
+                  options.dbRowGcInterval.getUnit().getTimeUnit()));
           expose(RowGarbageCollector.class);
         }
       });

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java b/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
index 835f160..6fdf31d 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/log/LogStorageModule.java
@@ -14,25 +14,26 @@
 package org.apache.aurora.scheduler.storage.log;
 
 import java.util.Set;
+
 import javax.inject.Singleton;
 
-import com.google.common.annotations.VisibleForTesting;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.hash.HashFunction;
 import com.google.common.hash.Hashing;
 import com.google.inject.PrivateModule;
 import com.google.inject.TypeLiteral;
 import com.google.inject.assistedinject.FactoryModuleBuilder;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
 import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Data;
 import org.apache.aurora.common.quantity.Time;
+import org.apache.aurora.scheduler.config.types.DataAmount;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
 import org.apache.aurora.scheduler.storage.CallOrderEnforcingStorage;
 import org.apache.aurora.scheduler.storage.DistributedSnapshotStore;
 import org.apache.aurora.scheduler.storage.Storage;
 import org.apache.aurora.scheduler.storage.Storage.NonVolatileStorage;
-import org.apache.aurora.scheduler.storage.db.DbModule;
 import org.apache.aurora.scheduler.storage.log.LogManager.MaxEntrySize;
 import org.apache.aurora.scheduler.storage.log.LogStorage.Settings;
 import org.apache.aurora.scheduler.storage.log.SnapshotStoreImpl.ExperimentalTaskStore;
@@ -47,45 +48,52 @@ import static org.apache.aurora.scheduler.storage.log.SnapshotDeduplicator.Snaps
  */
 public class LogStorageModule extends PrivateModule {
 
-  @CmdLine(name = "dlog_shutdown_grace_period",
-           help = "Specifies the maximum time to wait for scheduled checkpoint and snapshot "
-                  + "actions to complete before forcibly shutting down.")
-  private static final Arg<Amount<Long, Time>> SHUTDOWN_GRACE_PERIOD =
-      Arg.create(Amount.of(2L, Time.SECONDS));
-
-  @CmdLine(name = "dlog_snapshot_interval",
-           help = "Specifies the frequency at which snapshots of local storage are taken and "
-                  + "written to the log.")
-  private static final Arg<Amount<Long, Time>> SNAPSHOT_INTERVAL =
-      Arg.create(Amount.of(1L, Time.HOURS));
-
-  @CmdLine(name = "dlog_max_entry_size",
-           help = "Specifies the maximum entry size to append to the log. Larger entries will be "
-                  + "split across entry Frames.")
-  @VisibleForTesting
-  public static final Arg<Amount<Integer, Data>> MAX_LOG_ENTRY_SIZE =
-      Arg.create(Amount.of(512, Data.KB));
-
-  @CmdLine(name = "snapshot_hydrate_stores",
-      help = "Which H2-backed stores to fully hydrate on the Snapshot.")
-  private static final Arg<Set<String>> HYDRATE_SNAPSHOT_FIELDS =
-      Arg.create(SnapshotStoreImpl.ALL_H2_STORE_FIELDS);
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-dlog_shutdown_grace_period",
+        description = "Specifies the maximum time to wait for scheduled checkpoint and snapshot "
+            + "actions to complete before forcibly shutting down.")
+    public TimeAmount shutdownGracePeriod = new TimeAmount(2, Time.SECONDS);
+
+    @Parameter(names = "-dlog_snapshot_interval",
+        description = "Specifies the frequency at which snapshots of local storage are taken and "
+            + "written to the log.")
+    public TimeAmount snapshotInterval = new TimeAmount(1, Time.HOURS);
+
+    @Parameter(names = "-dlog_max_entry_size",
+        description =
+            "Specifies the maximum entry size to append to the log. Larger entries will be "
+                + "split across entry Frames.")
+    public DataAmount maxLogEntrySize = new DataAmount(512, Data.KB);
+
+    @Parameter(names = "-snapshot_hydrate_stores",
+        description = "Which H2-backed stores to fully hydrate on the Snapshot.")
+    public Set<String> hydrateSnapshotFields = SnapshotStoreImpl.ALL_H2_STORE_FIELDS;
+  }
+
+  private final Options options;
+  private final boolean useDbTaskStore;
+
+  public LogStorageModule(Options options, boolean useDbTaskStore) {
+    this.options = options;
+    this.useDbTaskStore = useDbTaskStore;
+  }
 
   @Override
   protected void configure() {
     bind(Settings.class)
-        .toInstance(new Settings(SHUTDOWN_GRACE_PERIOD.get(), SNAPSHOT_INTERVAL.get()));
+        .toInstance(new Settings(options.shutdownGracePeriod, options.snapshotInterval));
 
     bind(new TypeLiteral<Boolean>() { }).annotatedWith(ExperimentalTaskStore.class)
-        .toInstance(DbModule.USE_DB_TASK_STORE.get());
+        .toInstance(useDbTaskStore);
 
     bind(new TypeLiteral<Amount<Integer, Data>>() { }).annotatedWith(MaxEntrySize.class)
-        .toInstance(MAX_LOG_ENTRY_SIZE.get());
+        .toInstance(options.maxLogEntrySize);
     bind(LogManager.class).in(Singleton.class);
     bind(LogStorage.class).in(Singleton.class);
 
     bind(new TypeLiteral<Set<String>>() { }).annotatedWith(HydrateSnapshotFields.class)
-        .toInstance(HYDRATE_SNAPSHOT_FIELDS.get());
+        .toInstance(options.hydrateSnapshotFields);
 
     install(CallOrderEnforcingStorage.wrappingModule(LogStorage.class));
     bind(DistributedSnapshotStore.class).to(LogStorage.class);

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java b/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
index 9d2164f..fdf9c33 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/log/SnapshotStoreImpl.java
@@ -118,7 +118,7 @@ public class SnapshotStoreImpl implements SnapshotStore<Snapshot> {
    * Used by LogStorageModule to maintain legacy behavior for a change to snapshot format
    * (and thus also backup processing) behavior. See AURORA-1861 for context.
    */
-  static final Set<String> ALL_H2_STORE_FIELDS = ImmutableSet.of(
+  public static final Set<String> ALL_H2_STORE_FIELDS = ImmutableSet.of(
       LOCK_FIELD,
       HOST_ATTRIBUTES_FIELD,
       QUOTA_FIELD,

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java b/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java
index 1b491f9..24296b6 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/mem/InMemStoresModule.java
@@ -19,13 +19,13 @@ import com.google.inject.Key;
 import com.google.inject.PrivateModule;
 import com.google.inject.TypeLiteral;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
 import org.apache.aurora.common.inject.Bindings.KeyFactory;
 import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.scheduler.storage.CronJobStore;
 import org.apache.aurora.scheduler.storage.TaskStore;
+import org.apache.aurora.scheduler.storage.db.DbModule;
+import org.apache.aurora.scheduler.storage.db.DbModule.Options;
 import org.apache.aurora.scheduler.storage.mem.MemTaskStore.SlowQueryThreshold;
 
 import static java.util.Objects.requireNonNull;
@@ -36,14 +36,12 @@ import static java.util.Objects.requireNonNull;
  * NOTE: These stores are being phased out in favor of database-backed stores.
  */
 public final class InMemStoresModule extends PrivateModule {
-  @CmdLine(name = "slow_query_log_threshold",
-      help = "Log all queries that take at least this long to execute.")
-  private static final Arg<Amount<Long, Time>> SLOW_QUERY_LOG_THRESHOLD =
-      Arg.create(Amount.of(25L, Time.MILLISECONDS));
 
+  private final Options options;
   private final KeyFactory keyFactory;
 
-  public InMemStoresModule(KeyFactory keyFactory) {
+  public InMemStoresModule(DbModule.Options options, KeyFactory keyFactory) {
+    this.options = requireNonNull(options);
     this.keyFactory = requireNonNull(keyFactory);
   }
 
@@ -58,7 +56,7 @@ public final class InMemStoresModule extends PrivateModule {
   @Override
   protected void configure() {
     bind(new TypeLiteral<Amount<Long, Time>>() { }).annotatedWith(SlowQueryThreshold.class)
-        .toInstance(SLOW_QUERY_LOG_THRESHOLD.get());
+        .toInstance(options.slowQueryLogThreshold);
     bindStore(TaskStore.Mutable.class, MemTaskStore.class);
     expose(TaskStore.Mutable.class);
     bindStore(CronJobStore.Mutable.class, MemCronJobStore.class);

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java b/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
index bd92ff7..58aed10 100644
--- a/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/thrift/ThriftModule.java
@@ -18,7 +18,6 @@ import com.google.inject.AbstractModule;
 import org.apache.aurora.gen.AuroraAdmin;
 import org.apache.aurora.gen.ReadOnlyScheduler;
 import org.apache.aurora.scheduler.thrift.aop.AnnotatedAuroraAdmin;
-import org.apache.aurora.scheduler.thrift.aop.AopModule;
 
 /**
  * Binding module to configure a thrift server.
@@ -34,7 +33,6 @@ public class ThriftModule extends AbstractModule {
     // Promote to an explicit binding so it's created in the servlet container child injector.
     // See https://code.google.com/p/google-guice/issues/detail?id=461
     bind(SchedulerThriftInterface.class);
-    install(new AopModule());
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java b/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
index ef5edf6..a66d804 100644
--- a/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/thrift/aop/AopModule.java
@@ -13,9 +13,11 @@
  */
 package org.apache.aurora.scheduler.thrift.aop;
 
-import java.util.Set;
+import java.util.List;
 
-import com.google.common.collect.ImmutableSet;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.AbstractModule;
 import com.google.inject.Binder;
 import com.google.inject.Module;
@@ -23,9 +25,9 @@ import com.google.inject.matcher.Matcher;
 import com.google.inject.matcher.Matchers;
 
 import org.aopalliance.intercept.MethodInterceptor;
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
 import org.apache.aurora.gen.Response;
+import org.apache.aurora.scheduler.app.MoreModules;
+import org.apache.aurora.scheduler.config.CliOptions;
 import org.apache.aurora.scheduler.thrift.auth.DecoratedThrift;
 
 /**
@@ -33,14 +35,24 @@ import org.apache.aurora.scheduler.thrift.auth.DecoratedThrift;
  */
 public class AopModule extends AbstractModule {
 
-  @CmdLine(name = "thrift_method_interceptor_modules",
-      help = "Custom Guice module(s) to provide additional Thrift method interceptors.")
-  private static final Arg<Set<Module>> METHOD_INTERCEPTOR_MODULES = Arg.create(ImmutableSet.of());
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-thrift_method_interceptor_modules",
+        description = "Custom Guice module(s) to provide additional Thrift method interceptors.")
+    @SuppressWarnings("rawtypes")
+    public List<Class> methodInterceptorModules = ImmutableList.of();
+  }
 
   public static final Matcher<? super Class<?>> THRIFT_IFACE_MATCHER =
       Matchers.subclassesOf(AnnotatedAuroraAdmin.class)
           .and(Matchers.annotatedWith(DecoratedThrift.class));
 
+  private final CliOptions options;
+
+  public AopModule(CliOptions options) {
+    this.options = options;
+  }
+
   @Override
   protected void configure() {
     // Layer ordering:
@@ -54,7 +66,9 @@ public class AopModule extends AbstractModule {
     bindThriftDecorator(new ThriftStatsExporterInterceptor());
 
     // Install custom interceptor modules
-    for (Module module : METHOD_INTERCEPTOR_MODULES.get()) {
+    for (Module module
+        : MoreModules.instantiateAll(options.aop.methodInterceptorModules, options)) {
+
       install(module);
     }
   }

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/java/org/apache/aurora/scheduler/updater/UpdaterModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/updater/UpdaterModule.java b/src/main/java/org/apache/aurora/scheduler/updater/UpdaterModule.java
index 3673031..74ee174 100644
--- a/src/main/java/org/apache/aurora/scheduler/updater/UpdaterModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/updater/UpdaterModule.java
@@ -18,18 +18,18 @@ import java.util.concurrent.ScheduledExecutorService;
 
 import javax.inject.Singleton;
 
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.AbstractModule;
 import com.google.inject.PrivateModule;
 import com.google.inject.TypeLiteral;
 
-import org.apache.aurora.common.args.Arg;
-import org.apache.aurora.common.args.CmdLine;
-import org.apache.aurora.common.quantity.Amount;
 import org.apache.aurora.common.quantity.Time;
 import org.apache.aurora.scheduler.SchedulerServicesModule;
 import org.apache.aurora.scheduler.base.AsyncUtil;
 import org.apache.aurora.scheduler.base.TaskGroupKey;
+import org.apache.aurora.scheduler.config.types.TimeAmount;
 import org.apache.aurora.scheduler.events.PubsubEventModule;
 import org.apache.aurora.scheduler.preemptor.BiCache;
 import org.apache.aurora.scheduler.preemptor.BiCache.BiCacheSettings;
@@ -43,25 +43,31 @@ import org.slf4j.LoggerFactory;
 public class UpdaterModule extends AbstractModule {
   private static final Logger LOG = LoggerFactory.getLogger(UpdaterModule.class);
 
-  private final ScheduledExecutorService executor;
-  private final boolean enableAffinity;
+  @Parameters(separators = "=")
+  public static class Options {
+    @Parameter(names = "-enable_update_affinity",
+        description = "Enable best-effort affinity of task updates.",
+        arity = 1)
+    public boolean enableAffinity = false;
 
-  @CmdLine(name = "enable_update_affinity", help = "Enable best-effort affinity of task updates.")
-  private static final Arg<Boolean> ENABLE_AFFINITY = Arg.create(false);
+    @Parameter(names = "-update_affinity_reservation_hold_time",
+        description = "How long to wait for a reserved agent to reoffer freed up resources.")
+    public TimeAmount affinityExpiration = new TimeAmount(3L, Time.MINUTES);
+  }
 
-  @CmdLine(name = "update_affinity_reservation_hold_time",
-      help = "How long to wait for a reserved agent to reoffer freed up resources.")
-  private static final Arg<Amount<Long, Time>> AFFINITY_EXPIRATION =
-      Arg.create(Amount.of(3L, Time.MINUTES));
+  private final ScheduledExecutorService executor;
+  private final Options options;
 
-  public UpdaterModule() {
-    this(AsyncUtil.singleThreadLoggingScheduledExecutor("updater-%d", LOG), ENABLE_AFFINITY.get());
+  public UpdaterModule(Options options) {
+    this(
+        AsyncUtil.singleThreadLoggingScheduledExecutor("updater-%d", LOG),
+        options);
   }
 
   @VisibleForTesting
-  UpdaterModule(ScheduledExecutorService executor, boolean enableAffinity) {
+  UpdaterModule(ScheduledExecutorService executor, Options options) {
     this.executor = Objects.requireNonNull(executor);
-    this.enableAffinity = enableAffinity;
+    this.options = options;
   }
 
   @Override
@@ -69,9 +75,9 @@ public class UpdaterModule extends AbstractModule {
     install(new PrivateModule() {
       @Override
       protected void configure() {
-        if (enableAffinity) {
+        if (options.enableAffinity) {
           bind(BiCacheSettings.class).toInstance(
-              new BiCacheSettings(AFFINITY_EXPIRATION.get(), "update_affinity"));
+              new BiCacheSettings(options.affinityExpiration, "update_affinity"));
           bind(new TypeLiteral<BiCache<IInstanceKey, TaskGroupKey>>() { }).in(Singleton.class);
           bind(UpdateAgentReserver.class).to(UpdateAgentReserver.UpdateAgentReserverImpl.class);
           bind(UpdateAgentReserver.UpdateAgentReserverImpl.class).in(Singleton.class);

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/main/resources/org/apache/aurora/scheduler/webhook.json
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/webhook.json b/src/main/resources/org/apache/aurora/scheduler/webhook.json
deleted file mode 100644
index e645f64..0000000
--- a/src/main/resources/org/apache/aurora/scheduler/webhook.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "headers": {
-    "Content-Type": "application/vnd.kafka.json.v1+json",
-    "Producer-Type": "reliable"
-  },
-  "targetURL": "http://localhost:8080/",
-  "timeoutMsec": 5000
-}

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/test/java/org/apache/aurora/scheduler/TierModuleTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/TierModuleTest.java b/src/test/java/org/apache/aurora/scheduler/TierModuleTest.java
index 58d95dc..b0a681c 100644
--- a/src/test/java/org/apache/aurora/scheduler/TierModuleTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/TierModuleTest.java
@@ -33,7 +33,7 @@ public class TierModuleTest {
 
   @Test
   public void testTierConfigArgumentNotSpecified() throws Exception {
-    String tierFileContents = readTierFile();
+    String tierFileContents = readTierFile(new TierModule.Options());
     assertFalse(Strings.isNullOrEmpty(tierFileContents));
     assertEquals(
         tierFileContents,

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/test/java/org/apache/aurora/scheduler/app/MoreModulesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/app/MoreModulesTest.java b/src/test/java/org/apache/aurora/scheduler/app/MoreModulesTest.java
index 1b23948..0c8471b 100644
--- a/src/test/java/org/apache/aurora/scheduler/app/MoreModulesTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/app/MoreModulesTest.java
@@ -13,11 +13,17 @@
  */
 package org.apache.aurora.scheduler.app;
 
+import java.util.Set;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
-import com.google.inject.Module;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
 
+import org.apache.aurora.scheduler.config.CliOptions;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -26,15 +32,16 @@ public class MoreModulesTest {
   private static final String STRING = "string";
 
   @Test
-  public void testLazilyInstantiated() {
-    Injector injector = Guice.createInjector(MoreModules.lazilyInstantiated(StringInstaller.class));
+  public void testInstantiate() {
+    CliOptions options = new CliOptions();
+    options.main.clusterName = "testing";
+    Injector injector = Guice.createInjector(MoreModules.instantiateAll(
+        ImmutableList.of(StringInstaller.class, StringSetInstaller.class),
+        options));
     assertEquals(STRING, injector.getInstance(String.class));
-  }
-
-  @Test
-  public void testToString() {
-    Module module = MoreModules.lazilyInstantiated(StringInstaller.class);
-    assertEquals(StringInstaller.class.toString(), module.toString());
+    assertEquals(
+        ImmutableSet.of(options.main.clusterName),
+        injector.getInstance(Key.get(new TypeLiteral<Set<String>>() { })));
   }
 
   static class StringInstaller extends AbstractModule {
@@ -43,4 +50,18 @@ public class MoreModulesTest {
       bind(String.class).toInstance(STRING);
     }
   }
+
+  public static class StringSetInstaller extends AbstractModule {
+    private final CliOptions options;
+
+    public StringSetInstaller(CliOptions options) {
+      this.options = options;
+    }
+
+    @Override
+    protected void configure() {
+      bind(new TypeLiteral<Set<String>>() { })
+          .toInstance(ImmutableSet.of(options.main.clusterName));
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java b/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
index a7c9c83..a363e70 100644
--- a/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
+++ b/src/test/java/org/apache/aurora/scheduler/app/SchedulerIT.java
@@ -43,6 +43,8 @@ import com.google.inject.Module;
 import org.apache.aurora.GuavaUtils;
 import org.apache.aurora.codec.ThriftBinaryCodec.CodingException;
 import org.apache.aurora.common.application.Lifecycle;
+import org.apache.aurora.common.quantity.Amount;
+import org.apache.aurora.common.quantity.Data;
 import org.apache.aurora.common.stats.Stats;
 import org.apache.aurora.common.zookeeper.Credentials;
 import org.apache.aurora.common.zookeeper.ServerSetImpl;
@@ -63,6 +65,7 @@ import org.apache.aurora.gen.storage.storageConstants;
 import org.apache.aurora.scheduler.AppStartup;
 import org.apache.aurora.scheduler.TierModule;
 import org.apache.aurora.scheduler.base.TaskTestUtil;
+import org.apache.aurora.scheduler.config.CliOptions;
 import org.apache.aurora.scheduler.configuration.executor.ExecutorSettings;
 import org.apache.aurora.scheduler.discovery.ServiceDiscoveryModule;
 import org.apache.aurora.scheduler.discovery.ZooKeeperConfig;
@@ -176,7 +179,7 @@ public class SchedulerIT extends BaseZooKeeperClientTest {
     logStream = control.createMock(Stream.class);
     streamMatcher = LogOpMatcher.matcherFor(logStream);
     entrySerializer = new EntrySerializer.EntrySerializerImpl(
-        LogStorageModule.MAX_LOG_ENTRY_SIZE.get(),
+        Amount.of(512, Data.KB),
         Hashing.md5());
 
     zkClient = createZkClient();
@@ -197,7 +200,11 @@ public class SchedulerIT extends BaseZooKeeperClientTest {
             mesosScalar(RAM_MB, 1));
         bind(ExecutorSettings.class)
             .toInstance(TestExecutorSettings.thermosOnlyWithOverhead(overhead));
-        install(new BackupModule(backupDir, SnapshotStoreImpl.class));
+
+        BackupModule.Options backupOptions = new BackupModule.Options();
+        backupOptions.backupDir = backupDir;
+
+        install(new BackupModule(backupOptions, SnapshotStoreImpl.class));
 
         bind(IServerInfo.class).toInstance(
             IServerInfo.build(
@@ -214,9 +221,9 @@ public class SchedulerIT extends BaseZooKeeperClientTest {
     SchedulerMain main = SchedulerMain.class.newInstance();
     Injector injector = Guice.createInjector(
         ImmutableList.<Module>builder()
-            .add(SchedulerMain.getUniversalModule())
+            .add(SchedulerMain.getUniversalModule(new CliOptions()))
             .add(new TierModule(TaskTestUtil.TIER_CONFIG))
-            .add(new LogStorageModule())
+            .add(new LogStorageModule(new LogStorageModule.Options(), false))
             .add(new ServiceDiscoveryModule(zkClientConfig, SERVERSET_PATH))
             .add(testModule)
             .build()
@@ -226,7 +233,7 @@ public class SchedulerIT extends BaseZooKeeperClientTest {
 
     executor.submit(() -> {
       try {
-        main.run();
+        main.run(new SchedulerMain.Options());
       } catch (RuntimeException e) {
         mainException.set(Optional.of(e));
         executor.shutdownNow();

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/test/java/org/apache/aurora/scheduler/app/VolumeConverterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/app/VolumeConverterTest.java b/src/test/java/org/apache/aurora/scheduler/app/VolumeConverterTest.java
new file mode 100644
index 0000000..fd1232d
--- /dev/null
+++ b/src/test/java/org/apache/aurora/scheduler/app/VolumeConverterTest.java
@@ -0,0 +1,55 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.app;
+
+import com.beust.jcommander.ParameterException;
+
+import org.apache.aurora.gen.Mode;
+import org.apache.aurora.gen.Volume;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class VolumeConverterTest {
+
+  private VolumeConverter volumeConverter;
+
+  @Before
+  public void setUp() {
+    volumeConverter = new VolumeConverter();
+  }
+
+  @Test
+  public void testValidConfig() {
+    assertEquals(
+        new Volume("/container", "/host", Mode.RO),
+        volumeConverter.convert("/host:/container:ro"));
+  }
+
+  @Test(expected = ParameterException.class)
+  public void testInvalidConfig() {
+    volumeConverter.convert("/host,nope");
+  }
+
+  @Test(expected = ParameterException.class)
+  public void testInvalidMode() {
+    volumeConverter.convert("/host:/container:RE");
+  }
+
+  @Test(expected = ParameterException.class)
+  public void testTooManySegments() {
+    volumeConverter.convert("/host:/container:RO:bonusdata");
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/test/java/org/apache/aurora/scheduler/app/VolumeParserTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/app/VolumeParserTest.java b/src/test/java/org/apache/aurora/scheduler/app/VolumeParserTest.java
deleted file mode 100644
index e8f8449..0000000
--- a/src/test/java/org/apache/aurora/scheduler/app/VolumeParserTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.aurora.scheduler.app;
-
-import org.apache.aurora.gen.Mode;
-import org.apache.aurora.gen.Volume;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class VolumeParserTest {
-
-  private VolumeParser volumeParser;
-
-  @Before
-  public void setUp() {
-    volumeParser = new VolumeParser();
-  }
-
-  @Test
-  public void testValidConfig() {
-    assertEquals(
-        new Volume("/container", "/host", Mode.RO),
-        volumeParser.doParse("/host:/container:ro"));
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testInvalidConfig() {
-    volumeParser.doParse("/host,nope");
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testInvalidMode() {
-    volumeParser.doParse("/host:/container:RE");
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void testTooManySegments() {
-    volumeParser.doParse("/host:/container:RO:bonusdata");
-  }
-}

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/test/java/org/apache/aurora/scheduler/app/local/LocalSchedulerMain.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/app/local/LocalSchedulerMain.java b/src/test/java/org/apache/aurora/scheduler/app/local/LocalSchedulerMain.java
index b63f014..3dee55a 100644
--- a/src/test/java/org/apache/aurora/scheduler/app/local/LocalSchedulerMain.java
+++ b/src/test/java/org/apache/aurora/scheduler/app/local/LocalSchedulerMain.java
@@ -32,6 +32,8 @@ import com.google.inject.util.Modules;
 import org.apache.aurora.scheduler.TierModule;
 import org.apache.aurora.scheduler.app.SchedulerMain;
 import org.apache.aurora.scheduler.app.local.simulator.ClusterSimulatorModule;
+import org.apache.aurora.scheduler.config.CliOptions;
+import org.apache.aurora.scheduler.config.CommandLine;
 import org.apache.aurora.scheduler.mesos.DriverFactory;
 import org.apache.aurora.scheduler.mesos.DriverSettings;
 import org.apache.aurora.scheduler.mesos.FrameworkInfoFactory;
@@ -79,7 +81,7 @@ public final class LocalSchedulerMain {
             + "org/apache/aurora/scheduler/http/api/security/shiro-example.ini")
         .add("-enable_h2_console=true")
         .build();
-    SchedulerMain.applyStaticArgumentValues(arguments.toArray(new String[] {}));
+    CliOptions options = CommandLine.parseOptions(arguments.toArray(new String[] {}));
 
     Module persistentStorage = new AbstractModule() {
       @Override
@@ -112,6 +114,7 @@ public final class LocalSchedulerMain {
     };
 
     SchedulerMain.flagConfiguredMain(
-        Modules.combine(fakeMesos, persistentStorage, new TierModule()));
+        options,
+        Modules.combine(fakeMesos, persistentStorage, new TierModule(options.tiers)));
   }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/519e3df7/src/test/java/org/apache/aurora/scheduler/async/AsyncModuleTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/async/AsyncModuleTest.java b/src/test/java/org/apache/aurora/scheduler/async/AsyncModuleTest.java
index 4c263f9..74956cd 100644
--- a/src/test/java/org/apache/aurora/scheduler/async/AsyncModuleTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/async/AsyncModuleTest.java
@@ -72,7 +72,7 @@ public class AsyncModuleTest extends EasyMockTest {
 
   @Test
   public void testBindings() throws Exception {
-    Injector injector = createInjector(new AsyncModule());
+    Injector injector = createInjector(new AsyncModule(new AsyncModule.Options()));
 
     control.replay();