aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From wfar...@apache.org
Subject svn commit: r1719617 [2/4] - in /aurora/site: publish/ publish/blog/ publish/blog/2015-upcoming-apache-aurora-meetups/ publish/blog/aurora-0-6-0-incubating-released/ publish/blog/aurora-0-7-0-incubating-released/ publish/blog/aurora-0-8-0-released/ pub...
Date Sat, 12 Dec 2015 01:46:49 GMT
Modified: aurora/site/publish/documentation/latest/configuration-tutorial/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/latest/configuration-tutorial/index.html?rev=1719617&r1=1719616&r2=1719617&view=diff
==============================================================================
--- aurora/site/publish/documentation/latest/configuration-tutorial/index.html (original)
+++ aurora/site/publish/documentation/latest/configuration-tutorial/index.html Sat Dec 12 01:46:48 2015
@@ -21,12 +21,11 @@
 	</script>
   </head>
   <body>
-	  
         <div class="container-fluid section-header">
   <div class="container">
     <div class="nav nav-bar">
     <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
-	<ul class="nav navbar-nav navbar-right">
+    <ul class="nav navbar-nav navbar-right">
       <li><a href="/documentation/latest/">Documentation</a></li>
       <li><a href="/community/">Community</a></li>
       <li><a href="/downloads/">Downloads</a></li>
@@ -34,7 +33,8 @@
     </ul>
     </div>
   </div>
-</div>	
+</div>
+	
   	  <div class="container-fluid">
   	  	<div class="container content">
           <div class="col-md-12 documentation">
@@ -183,32 +183,32 @@ parts you don&rsquo;t understand yet, bu
 as you read about its individual parts. Note that names surrounded by
 curly braces {{}} are template variables, which the system replaces with
 bound values for the variables.</p>
-<pre class="highlight text"># --- templates here ---
+<pre class="highlight plaintext"><code># --- templates here ---
 class Profile(Struct):
-  package_version = Default(String, &#39;live&#39;)
-  java_binary = Default(String, &#39;/usr/lib/jvm/java-1.7.0-openjdk/bin/java&#39;)
-  extra_jvm_options = Default(String, &#39;&#39;)
-  parent_environment = Default(String, &#39;prod&#39;)
+  package_version = Default(String, 'live')
+  java_binary = Default(String, '/usr/lib/jvm/java-1.7.0-openjdk/bin/java')
+  extra_jvm_options = Default(String, '')
+  parent_environment = Default(String, 'prod')
   parent_serverset = Default(String,
-                             &#39;/foocorp/service/bird/{{parent_environment}}/bird&#39;)
+                             '/foocorp/service/bird/{{parent_environment}}/bird')
 
 # --- processes here ---
 main = Process(
-  name = &#39;application&#39;,
-  cmdline = &#39;{{profile.java_binary}} -server -Xmx1792m &#39;
-            &#39;{{profile.extra_jvm_options}} &#39;
-            &#39;-jar application.jar &#39;
-            &#39;-upstreamService {{profile.parent_serverset}}&#39;
+  name = 'application',
+  cmdline = '{{profile.java_binary}} -server -Xmx1792m '
+            '{{profile.extra_jvm_options}} '
+            '-jar application.jar '
+            '-upstreamService {{profile.parent_serverset}}'
 )
 
 # --- tasks ---
 base_task = SequentialTask(
-  name = &#39;application&#39;,
+  name = 'application',
   processes = [
     Process(
-      name = &#39;fetch&#39;,
-      cmdline = &#39;curl -O
-              https://packages.foocorp.com/{{profile.package_version}}/application.jar&#39;),
+      name = 'fetch',
+      cmdline = 'curl -O
+              https://packages.foocorp.com/{{profile.package_version}}/application.jar'),
   ]
 )
 
@@ -225,9 +225,9 @@ production_task = base_task(resources =
 
 # --- job template ---
 job_template = Job(
-  name = &#39;application&#39;,
-  role = &#39;myteam&#39;,
-  contact = &#39;myteam-team@foocorp.com&#39;,
+  name = 'application',
+  role = 'myteam',
+  contact = 'myteam-team@foocorp.com',
   instances = 20,
   service = True,
   task = production_task
@@ -236,26 +236,27 @@ job_template = Job(
 # -- profile instantiations (if any) ---
 PRODUCTION = Profile()
 STAGING = Profile(
-  extra_jvm_options = &#39;-Xloggc:gc.log&#39;,
-  parent_environment = &#39;staging&#39;
+  extra_jvm_options = '-Xloggc:gc.log',
+  parent_environment = 'staging'
 )
 
 # -- job instantiations --
 jobs = [
-      job_template(cluster = &#39;cluster1&#39;, environment = &#39;prod&#39;)
+      job_template(cluster = 'cluster1', environment = 'prod')
                .bind(profile = PRODUCTION),
 
-      job_template(cluster = &#39;cluster2&#39;, environment = &#39;prod&#39;)
+      job_template(cluster = 'cluster2', environment = 'prod')
                 .bind(profile = PRODUCTION),
 
-      job_template(cluster = &#39;cluster1&#39;,
-                    environment = &#39;staging&#39;,
+      job_template(cluster = 'cluster1',
+                    environment = 'staging',
         service = False,
         task = staging_task,
         instances = 2)
         .bind(profile = STAGING),
 ]
-</pre>
+</code></pre>
+
 <h2 id="defining-process-objects">Defining Process Objects</h2>
 
 <p>Processes are handled by the Thermos system. A process is a single
@@ -275,27 +276,28 @@ so <code>$*</code> is unspecified.</li>
 
 <p>Many tiny processes make managing configurations more difficult. For
 example, the following is a bad way to define processes.</p>
-<pre class="highlight text">copy = Process(
-  name = &#39;copy&#39;,
-  cmdline = &#39;curl -O https://packages.foocorp.com/app.zip&#39;
+<pre class="highlight plaintext"><code>copy = Process(
+  name = 'copy',
+  cmdline = 'curl -O https://packages.foocorp.com/app.zip'
 )
 unpack = Process(
-  name = &#39;unpack&#39;,
-  cmdline = &#39;unzip app.zip&#39;
+  name = 'unpack',
+  cmdline = 'unzip app.zip'
 )
 remove = Process(
-  name = &#39;remove&#39;,
-  cmdline = &#39;rm -f app.zip&#39;
+  name = 'remove',
+  cmdline = 'rm -f app.zip'
 )
 run = Process(
-  name = &#39;app&#39;,
-  cmdline = &#39;java -jar app.jar&#39;
+  name = 'app',
+  cmdline = 'java -jar app.jar'
 )
 run_task = Task(
   processes = [copy, unpack, remove, run],
   constraints = order(copy, unpack, remove, run)
 )
-</pre>
+</code></pre>
+
 <p>Since <code>cmdline</code> runs in a bash subshell, you can chain commands
 with <code>&amp;&amp;</code> or <code>||</code>.</p>
 
@@ -303,64 +305,17 @@ with <code>&amp;&amp;</code> or <code>||
 particular order, use <code>SequentialTask</code>, as described in the <a href="#Task"><em>Defining</em>
 <code>Task</code> <em>Objects</em></a> section. The following simplifies and combines the
 above multiple <code>Process</code> definitions into just two.</p>
-<pre class="highlight text">stage = Process(
-  name = &#39;stage&#39;,
-  cmdline = &#39;curl -O https://packages.foocorp.com/app.zip &amp;&amp; &#39;
-            &#39;unzip app.zip &amp;&amp; rm -f app.zip&#39;)
+<pre class="highlight plaintext"><code>stage = Process(
+  name = 'stage',
+  cmdline = 'curl -O https://packages.foocorp.com/app.zip &amp;&amp; '
+            'unzip app.zip &amp;&amp; rm -f app.zip')
 
-run = Process(name = &#39;app&#39;, cmdline = &#39;java -jar app.jar&#39;)
+run = Process(name = 'app', cmdline = 'java -jar app.jar')
 
 run_task = SequentialTask(processes = [stage, run])
-</pre>
-<p><code>Process</code> also has five optional attributes, each with a default value
-if one isn&rsquo;t specified in the configuration:</p>
+</code></pre>
 
-<ul>
-<li><p><code>max_failures</code>: Defaulting to <code>1</code>, the maximum number of failures
-(non-zero exit statuses) before this <code>Process</code> is marked permanently
-failed and not retried. If a <code>Process</code> permanently fails, Thermos
-checks the <code>Process</code> object&rsquo;s containing <code>Task</code> for the task&rsquo;s
-failure limit (usually 1) to determine whether or not the <code>Task</code>
-should be failed. Setting <code>max_failures</code>to <code>0</code> means that this
-process will keep retrying until a successful (zero) exit status is
-achieved. Retries happen at most once every <code>min_duration</code> seconds
-to prevent effectively mounting a denial of service attack against
-the coordinating scheduler.</p></li>
-<li><p><code>daemon</code>: Defaulting to <code>False</code>, if <code>daemon</code> is set to <code>True</code>, a
-successful (zero) exit status does not prevent future process runs.
-Instead, the <code>Process</code> reinvokes after <code>min_duration</code> seconds.
-However, the maximum failure limit (<code>max_failures</code>) still
-applies. A combination of <code>daemon=True</code> and <code>max_failures=0</code> retries
-a <code>Process</code> indefinitely regardless of exit status. This should
-generally be avoided for very short-lived processes because of the
-accumulation of checkpointed state for each process run. When
-running in Aurora, <code>max_failures</code> is capped at
-100.</p></li>
-<li><p><code>ephemeral</code>: Defaulting to <code>False</code>, if <code>ephemeral</code> is <code>True</code>, the
-<code>Process</code>&rsquo; status is not used to determine if its bound <code>Task</code> has
-completed. For example, consider a <code>Task</code> with a
-non-ephemeral webserver process and an ephemeral logsaver process
-that periodically checkpoints its log files to a centralized data
-store. The <code>Task</code> is considered finished once the webserver process
-finishes, regardless of the logsaver&rsquo;s current status.</p></li>
-<li><p><code>min_duration</code>: Defaults to <code>15</code>. Processes may succeed or fail
-multiple times during a single Task. Each result is called a
-<em>process run</em> and this value is the minimum number of seconds the
-scheduler waits before re-running the same process.</p></li>
-<li><p><code>final</code>: Defaulting to <code>False</code>, this is a finalizing <code>Process</code> that
-should run last. Processes can be grouped into two classes:
-<em>ordinary</em> and <em>finalizing</em>. By default, Thermos Processes are
-ordinary. They run as long as the <code>Task</code> is considered
-healthy (i.e. hasn&rsquo;t reached a failure limit). But once all regular
-Thermos Processes have either finished or the <code>Task</code> has reached a
-certain failure threshold, Thermos moves into a <em>finalization</em> stage
-and runs all finalizing Processes. These are typically necessary for
-cleaning up after the <code>Task</code>, such as log checkpointers, or perhaps
-e-mail notifications of a completed Task. Finalizing processes may
-not depend upon ordinary processes or vice-versa, however finalizing
-processes may depend upon other finalizing processes and will
-otherwise run as a typical process schedule.</p></li>
-</ul>
+<p><code>Process</code> also has optional attributes to customize its behaviour. Details can be found in the <a href="configuration-reference.md#process-objects"><em>Aurora+Thermos Configuration Reference</em></a>.</p>
 
 <h2 id="getting-your-code-into-the-sandbox">Getting Your Code Into The Sandbox</h2>
 
@@ -379,11 +334,12 @@ the Internet, such as S3. For a private
 on an accessible HDFS cluster or similar storage.</p>
 
 <p>The template for this Process is:</p>
-<pre class="highlight text">&lt;name&gt; = Process(
-  name = &#39;&lt;name&gt;&#39;
-  cmdline = &#39;&lt;command to copy and extract code archive into current working directory&gt;&#39;
+<pre class="highlight plaintext"><code>&lt;name&gt; = Process(
+  name = '&lt;name&gt;'
+  cmdline = '&lt;command to copy and extract code archive into current working directory&gt;'
 )
-</pre>
+</code></pre>
+
 <p>Note: Be sure the extracted code archive has an executable.</p>
 
 <h2 id="defining-task-objects">Defining Task Objects</h2>
@@ -411,64 +367,15 @@ the processes run in parallel or sequent
 </ul>
 
 <p>A basic Task definition looks like:</p>
-<pre class="highlight text">Task(
-    name=&quot;hello_world&quot;,
-    processes=[Process(name = &quot;hello_world&quot;, cmdline = &quot;echo hello world&quot;)],
+<pre class="highlight plaintext"><code>Task(
+    name="hello_world",
+    processes=[Process(name = "hello_world", cmdline = "echo hello world")],
     resources=Resources(cpu = 1.0,
                         ram = 1*GB,
                         disk = 1*GB))
-</pre>
-<p>There are four optional Task attributes:</p>
+</code></pre>
 
-<ul>
-<li><p><code>constraints</code>: A list of <code>Constraint</code> objects that constrain the
-Task&rsquo;s processes. Currently there is only one type, the <code>order</code>
-constraint. For example the following requires that the processes
-run in the order <code>foo</code>, then <code>bar</code>.</p>
-<pre class="highlight text">constraints = [Constraint(order=[&#39;foo&#39;, &#39;bar&#39;])]
-</pre>
-<p>There is an <code>order()</code> function that takes <code>order(&#39;foo&#39;, &#39;bar&#39;, &#39;baz&#39;)</code>
-and converts it into <code>[Constraint(order=[&#39;foo&#39;, &#39;bar&#39;, &#39;baz&#39;])]</code>.
-<code>order()</code> accepts Process name strings <code>(&#39;foo&#39;, &#39;bar&#39;)</code> or the processes
-themselves, e.g. <code>foo=Process(name=&#39;foo&#39;, ...)</code>, <code>bar=Process(name=&#39;bar&#39;, ...)</code>,
-<code>constraints=order(foo, bar)</code></p>
-
-<p>Note that Thermos rejects tasks with process cycles.</p></li>
-<li><p><code>max_failures</code>: Defaulting to <code>1</code>, the number of failed processes
-needed for the <code>Task</code> to be marked as failed. Note how this
-interacts with individual Processes&rsquo; <code>max_failures</code> values. Assume a
-Task has two Processes and a <code>max_failures</code> value of <code>2</code>. So both
-Processes must fail for the Task to fail. Now, assume each of the
-Task&rsquo;s Processes has its own <code>max_failures</code> value of <code>10</code>. If
-Process &ldquo;A&rdquo; fails 5 times before succeeding, and Process &ldquo;B&rdquo; fails
-10 times and is then marked as failing, their parent Task succeeds.
-Even though there were 15 individual failures by its Processes, only
-1 of its Processes was finally marked as failing. Since 1 is less
-than the 2 that is the Task&rsquo;s <code>max_failures</code> value, the Task does
-not fail.</p></li>
-<li><p><code>max_concurrency</code>: Defaulting to <code>0</code>, the maximum number of
-concurrent processes in the Task. <code>0</code> specifies unlimited
-concurrency. For Tasks with many expensive but otherwise independent
-processes, you can limit the amount of concurrency Thermos schedules
-instead of artificially constraining them through <code>order</code>
-constraints. For example, a test framework may generate a Task with
-100 test run processes, but runs it in a Task with
-<code>resources.cpus=4</code>. Limit the amount of parallelism to 4 by setting
-<code>max_concurrency=4</code>.</p></li>
-<li><p><code>finalization_wait</code>: Defaulting to <code>30</code>, the number of seconds
-allocated for finalizing the Task&rsquo;s processes. A Task starts in
-<code>ACTIVE</code> state when Processes run and stays there as long as the Task
-is healthy and Processes run. When all Processes finish successfully
-or the Task reaches its maximum process failure limit, it goes into
-<code>CLEANING</code> state. In <code>CLEANING</code>, it sends <code>SIGTERMS</code> to any still running
-Processes. When all Processes terminate, the Task goes into
-<code>FINALIZING</code> state and invokes the schedule of all processes whose
-final attribute has a True value. Everything from the end of <code>ACTIVE</code>
-to the end of <code>FINALIZING</code> must happen within <code>finalization_wait</code>
-number of seconds. If not, all still running Processes are sent
-<code>SIGKILL</code>s (or if dependent on yet to be completed Processes, are
-never invoked).</p></li>
-</ul>
+<p>A Task has optional attributes to customize its behaviour. Details can be found in the <a href="configuration-reference.md#task-object"><em>Aurora+Thermos Configuration Reference</em></a></p>
 
 <h3 id="sequentialtask-running-processes-in-parallel-or-sequentially">SequentialTask: Running Processes in Parallel or Sequentially</h3>
 
@@ -478,14 +385,14 @@ are two ways to run Processes sequential
 <ul>
 <li><p>Include an <code>order</code> constraint in the Task definition&rsquo;s <code>constraints</code>
 attribute whose arguments specify the processes&rsquo; run order:</p>
-<pre class="highlight text">Task( ... processes=[process1, process2, process3],
+<pre class="highlight plaintext"><code>Task( ... processes=[process1, process2, process3],
       constraints = order(process1, process2, process3), ...)
-</pre></li>
+</code></pre></li>
 <li><p>Use <code>SequentialTask</code> instead of <code>Task</code>; it automatically runs
 processes in the order specified in the <code>processes</code> attribute. No
 <code>constraint</code> parameter is needed:</p>
-<pre class="highlight text">SequentialTask( ... processes=[process1, process2, process3] ...)
-</pre></li>
+<pre class="highlight plaintext"><code>SequentialTask( ... processes=[process1, process2, process3] ...)
+</code></pre></li>
 </ul>
 
 <h3 id="simpletask">SimpleTask</h3>
@@ -494,22 +401,25 @@ processes in the order specified in the
 creates a basic task from a provided name and command line using a
 default set of resources. For example, in a .<code>aurora</code> configuration
 file:</p>
-<pre class="highlight text">SimpleTask(name=&quot;hello_world&quot;, command=&quot;echo hello world&quot;)
-</pre>
+<pre class="highlight plaintext"><code>SimpleTask(name="hello_world", command="echo hello world")
+</code></pre>
+
 <p>is equivalent to</p>
-<pre class="highlight text">Task(name=&quot;hello_world&quot;,
-     processes=[Process(name = &quot;hello_world&quot;, cmdline = &quot;echo hello world&quot;)],
+<pre class="highlight plaintext"><code>Task(name="hello_world",
+     processes=[Process(name = "hello_world", cmdline = "echo hello world")],
      resources=Resources(cpu = 1.0,
                          ram = 1*GB,
                          disk = 1*GB))
-</pre>
+</code></pre>
+
 <p>The simplest idiomatic Job configuration thus becomes:</p>
-<pre class="highlight text">import os
+<pre class="highlight plaintext"><code>import os
 hello_world_job = Job(
-  task=SimpleTask(name=&quot;hello_world&quot;, command=&quot;echo hello world&quot;),
-  role=os.getenv(&#39;USER&#39;),
-  cluster=&quot;cluster1&quot;)
-</pre>
+  task=SimpleTask(name="hello_world", command="echo hello world"),
+  role=os.getenv('USER'),
+  cluster="cluster1")
+</code></pre>
+
 <p>When written to <code>hello_world.aurora</code>, you invoke it with a simple
 <code>aurora job create cluster1/$USER/test/hello_world hello_world.aurora</code>.</p>
 
@@ -539,7 +449,7 @@ maximum value specified by any subtask f
 </ul>
 
 <p>For example, given the following:</p>
-<pre class="highlight text">setup_task = Task(
+<pre class="highlight plaintext"><code>setup_task = Task(
   ...
   processes=[download_interpreter, update_zookeeper],
   # It is important to note that {{Tasks.concat}} has
@@ -558,11 +468,12 @@ run_task = SequentialTask(
 )
 
 combined_task = Tasks.concat(setup_task, run_task)
-</pre>
+</code></pre>
+
 <p>The <code>Tasks.concat</code> command merges the two Tasks into a single Task and
 ensures all processes in <code>setup_task</code> run before the processes
 in <code>run_task</code>. Conceptually, the task is reduced to:</p>
-<pre class="highlight text">task = Task(
+<pre class="highlight plaintext"><code>task = Task(
   ...
   processes=[download_interpreter, update_zookeeper,
              download_application, start_application],
@@ -570,9 +481,10 @@ in <code>run_task</code>. Conceptually,
                     download_application, start_application),
   ...
 )
-</pre>
+</code></pre>
+
 <p>In the case of <code>Tasks.combine</code>, the two schedules run in parallel:</p>
-<pre class="highlight text">task = Task(
+<pre class="highlight plaintext"><code>task = Task(
   ...
   processes=[download_interpreter, update_zookeeper,
              download_application, start_application],
@@ -580,7 +492,8 @@ in <code>run_task</code>. Conceptually,
                     order(download_application, start_application),
   ...
 )
-</pre>
+</code></pre>
+
 <p>In the latter case, each of the two sequences may operate in parallel.
 Of course, this may not be the intended behavior (for example, if
 the <code>start_application</code> Process implicitly relies
@@ -613,98 +526,13 @@ only run the Job whose job key includes
 <p>You usually see a <code>name</code> parameter. By default, <code>name</code> inherits its
 value from the Job&rsquo;s associated Task object, but you can override this
 default. For these four parameters, a Job definition might look like:</p>
-<pre class="highlight text">foo_job = Job( name = &#39;foo&#39;, cluster = &#39;cluster1&#39;,
-          role = os.getenv(&#39;USER&#39;), environment = &#39;prod&#39;,
+<pre class="highlight plaintext"><code>foo_job = Job( name = 'foo', cluster = 'cluster1',
+          role = os.getenv('USER'), environment = 'prod',
           task = foo_task)
-</pre>
-<p>In addition to the required attributes, there are several optional
-attributes. The first (strongly recommended) optional attribute is:</p>
-
-<ul>
-<li>  <code>contact</code>: An email address for the Job&rsquo;s owner. For production
-jobs, it is usually a team mailing list.</li>
-</ul>
-
-<p>Two more attributes deal with how to handle failure of the Job&rsquo;s Task:</p>
-
-<ul>
-<li><p><code>max_task_failures</code>: An integer, defaulting to <code>1</code>, of the maximum
-number of Task failures after which the Job is considered failed.
-<code>-1</code> allows for infinite failures.</p></li>
-<li><p><code>service</code>: A boolean, defaulting to <code>False</code>, which if <code>True</code>
-restarts tasks regardless of whether they succeeded or failed. In
-other words, if <code>True</code>, after the Job&rsquo;s Task completes, it
-automatically starts again. This is for Jobs you want to run
-continuously, rather than doing a single run.</p></li>
-</ul>
-
-<p>Three attributes deal with configuring the Job&rsquo;s Task:</p>
-
-<ul>
-<li><p><code>instances</code>: Defaulting to <code>1</code>, the number of
-instances/replicas/shards of the Job&rsquo;s Task to create.</p></li>
-<li><p><code>priority</code>: Defaulting to <code>0</code>, the Job&rsquo;s Task&rsquo;s preemption priority,
-for which higher values may preempt Tasks from Jobs with lower
-values.</p></li>
-<li><p><code>production</code>: a Boolean, defaulting to <code>False</code>, specifying that this
-is a production job backed by quota. Tasks from production Jobs may
-preempt tasks from any non-production job, and may only be preempted
-by tasks from production jobs in the same role with higher
-priority. <strong>WARNING</strong>: To run Jobs at this level, the Job role must
-have the appropriate quota. To grant quota to a particular role in
-production, operators use the <code>aurora_admin set_quota</code> command.</p></li>
-</ul>
-
-<p>The final three Job attributes each take an object as their value.</p>
-
-<ul>
-<li>  <code>update_config</code>: An <code>UpdateConfig</code>
-object provides parameters for controlling the rate and policy of
-rolling updates. The <code>UpdateConfig</code> parameters are:
+</code></pre>
 
-<ul>
-<li>  <code>batch_size</code>: An integer, defaulting to <code>1</code>, specifying the
-maximum number of shards to update in one iteration.</li>
-<li>  <code>restart_threshold</code>: An integer, defaulting to <code>60</code>, specifying
-the maximum number of seconds before a shard must move into the
-<code>RUNNING</code> state before considered a failure.</li>
-<li>  <code>watch_secs</code>: An integer, defaulting to <code>45</code>, specifying the
-minimum number of seconds a shard must remain in the <code>RUNNING</code>
-state before considered a success.</li>
-<li>  <code>max_per_shard_failures</code>: An integer, defaulting to <code>0</code>,
-specifying the maximum number of restarts per shard during an
-update. When the limit is exceeded, it increments the total
-failure count.</li>
-<li>  <code>max_total_failures</code>: An integer, defaulting to <code>0</code>, specifying
-the maximum number of shard failures tolerated during an update.
-Cannot be equal to or greater than the job&rsquo;s total number of
-tasks.</li>
-</ul></li>
-<li>  <code>health_check_config</code>: A <code>HealthCheckConfig</code> object that provides
-parameters for controlling a Task&rsquo;s health checks via HTTP. Only
-used if a health port was assigned with a command line wildcard. The
-<code>HealthCheckConfig</code> parameters are:
-
-<ul>
-<li>  <code>initial_interval_secs</code>: An integer, defaulting to <code>15</code>,
-specifying the initial delay for doing an HTTP health check.</li>
-<li>  <code>interval_secs</code>: An integer, defaulting to <code>10</code>, specifying the
-number of seconds in the interval between checking the Task&rsquo;s
-health.</li>
-<li>  <code>timeout_secs</code>: An integer, defaulting to <code>1</code>, specifying the
-number of seconds the application must respond to an HTTP health
-check with <code>OK</code> before it is considered a failure.</li>
-<li>  <code>max_consecutive_failures</code>: An integer, defaulting to <code>0</code>,
-specifying the maximum number of consecutive failures before a
-task is unhealthy.</li>
-</ul></li>
-<li>  <code>constraints</code>: A <code>dict</code> Python object, specifying Task scheduling
-constraints. Most users will not need to specify constraints, as the
-scheduler automatically inserts reasonable defaults. Please do not
-set this field unless you are sure of what you are doing. See the
-section in the Aurora + Thermos Reference manual on <a href="/documentation/latest/configuration-reference/">Specifying
-Scheduling Constraints</a> for more information.</li>
-</ul>
+<p>In addition to the required attributes, there are several optional
+attributes. Details can be found in the <a href="configuration-reference.md#job-objects">Aurora+Thermos Configuration Reference</a>.</p>
 
 <h2 id="the-jobs-list">The jobs List</h2>
 
@@ -743,18 +571,22 @@ are evaluated iteratively, so this affor
 
 <p>Let&rsquo;s start with the simplest template; text with one
 variable, in this case <code>name</code>;</p>
-<pre class="highlight text">Hello {{name}}
-</pre>
+<pre class="highlight plaintext"><code>Hello {{name}}
+</code></pre>
+
 <p>If we evaluate this as is, we&rsquo;d get back:</p>
-<pre class="highlight text">Hello
-</pre>
+<pre class="highlight plaintext"><code>Hello
+</code></pre>
+
 <p>If a template variable doesn&rsquo;t have a value, when evaluated it&rsquo;s
 replaced with nothing. If we add a binding to give it a value:</p>
-<pre class="highlight json"><span class="p">{</span><span class="w"> </span><span class="s2">&quot;name&quot;</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;Tom&quot;</span><span class="w"> </span><span class="p">}</span><span class="w">
-</span></pre>
+<pre class="highlight json"><code><span class="p">{</span><span class="w"> </span><span class="nt">"name"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"Tom"</span><span class="w"> </span><span class="p">}</span><span class="w">
+</span></code></pre>
+
 <p>We&rsquo;d get back:</p>
-<pre class="highlight text">Hello Tom
-</pre>
+<pre class="highlight plaintext"><code>Hello Tom
+</code></pre>
+
 <p>Every Pystachio object has an associated <code>.bind</code> method that can bind
 values to {{}} variables. Bindings are not immediately evaluated.
 Instead, they are evaluated only when the interpolated value of the
@@ -763,20 +595,20 @@ message over the wire.</p>
 
 <p>Objects with and without mustache templated variables behave
 differently:</p>
-<pre class="highlight text">&gt;&gt;&gt; Float(1.5)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; Float(1.5)
 Float(1.5)
 
-&gt;&gt;&gt; Float(&#39;{{x}}.5&#39;)
+&gt;&gt;&gt; Float('{{x}}.5')
 Float({{x}}.5)
 
-&gt;&gt;&gt; Float(&#39;{{x}}.5&#39;).bind(x = 1)
+&gt;&gt;&gt; Float('{{x}}.5').bind(x = 1)
 Float(1.5)
 
-&gt;&gt;&gt; Float(&#39;{{x}}.5&#39;).bind(x = 1) == Float(1.5)
+&gt;&gt;&gt; Float('{{x}}.5').bind(x = 1) == Float(1.5)
 True
 
-&gt;&gt;&gt; contextual_object = String(&#39;{{metavar{{number}}}}&#39;).bind(
-... metavar1 = &quot;first&quot;, metavar2 = &quot;second&quot;)
+&gt;&gt;&gt; contextual_object = String('{{metavar{{number}}}}').bind(
+... metavar1 = "first", metavar2 = "second")
 
 &gt;&gt;&gt; contextual_object
 String({{metavar{{number}}}})
@@ -786,7 +618,8 @@ String(first)
 
 &gt;&gt;&gt; contextual_object.bind(number = 2)
 String(second)
-</pre>
+</code></pre>
+
 <p>You usually bind simple key to value pairs, but you can also bind three
 other objects: lists, dictionaries, and structurals. These will be
 described in detail later.</p>
@@ -799,7 +632,7 @@ with derived structural (<code>Struct</c
 fundamental and structural objects. The structural object components are
 called <em>attributes</em>. Aurora&rsquo;s most used structural objects are <code>Job</code>,
 <code>Task</code>, and <code>Process</code>:</p>
-<pre class="highlight text">class Process(Struct):
+<pre class="highlight plaintext"><code>class Process(Struct):
   cmdline = Required(String)
   name = Required(String)
   max_failures = Default(Integer, 1)
@@ -807,35 +640,39 @@ called <em>attributes</em>. Aurora&rsquo
   ephemeral = Default(Boolean, False)
   min_duration = Default(Integer, 5)
   final = Default(Boolean, False)
-</pre>
+</code></pre>
+
 <p>Construct default objects by following the object&rsquo;s type with (). If you
 want an attribute to have a value different from its default, include
 the attribute name and value inside the parentheses.</p>
-<pre class="highlight text">&gt;&gt;&gt; Process()
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; Process()
 Process(daemon=False, max_failures=1, ephemeral=False,
   min_duration=5, final=False)
-</pre>
+</code></pre>
+
 <p>Attribute values can be template variables, which then receive specific
 values when creating the object.</p>
-<pre class="highlight text">&gt;&gt;&gt; Process(cmdline = &#39;echo {{message}}&#39;)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; Process(cmdline = 'echo {{message}}')
 Process(daemon=False, max_failures=1, ephemeral=False, min_duration=5,
         cmdline=echo {{message}}, final=False)
 
-&gt;&gt;&gt; Process(cmdline = &#39;echo {{message}}&#39;).bind(message = &#39;hello world&#39;)
+&gt;&gt;&gt; Process(cmdline = 'echo {{message}}').bind(message = 'hello world')
 Process(daemon=False, max_failures=1, ephemeral=False, min_duration=5,
         cmdline=echo hello world, final=False)
-</pre>
+</code></pre>
+
 <p>A powerful binding property is that all of an object&rsquo;s children inherit its
 bindings:</p>
-<pre class="highlight text">&gt;&gt;&gt; List(Process)([
-... Process(name = &#39;{{prefix}}_one&#39;),
-... Process(name = &#39;{{prefix}}_two&#39;)
-... ]).bind(prefix = &#39;hello&#39;)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; List(Process)([
+... Process(name = '{{prefix}}_one'),
+... Process(name = '{{prefix}}_two')
+... ]).bind(prefix = 'hello')
 ProcessList(
   Process(daemon=False, name=hello_one, max_failures=1, ephemeral=False, min_duration=5, final=False),
   Process(daemon=False, name=hello_two, max_failures=1, ephemeral=False, min_duration=5, final=False)
   )
-</pre>
+</code></pre>
+
 <p>Remember that an Aurora Job contains Tasks which contain Processes. A
 Job level binding is inherited by its Tasks and all their Processes.
 Similarly a Task level binding is available to that Task and its
@@ -854,20 +691,23 @@ defined as Mustache variables, implicitl
 inherit all child objects once they are defined.</p>
 
 <p>Thus, you can do the following:</p>
-<pre class="highlight text">&gt;&gt;&gt; Process(name = &quot;installer&quot;, cmdline = &quot;echo {{name}} is running&quot;)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; Process(name = "installer", cmdline = "echo {{name}} is running")
 Process(daemon=False, name=installer, max_failures=1, ephemeral=False, min_duration=5,
         cmdline=echo installer is running, final=False)
-</pre>
+</code></pre>
+
 <p>WARNING: This binding only takes place in one direction. For example,
 the following does NOT work and does not set the <code>Process</code> <code>name</code>
 attribute&rsquo;s value.</p>
-<pre class="highlight text">&gt;&gt;&gt; Process().bind(name = &quot;installer&quot;)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; Process().bind(name = "installer")
 Process(daemon=False, max_failures=1, ephemeral=False, min_duration=5, final=False)
-</pre>
+</code></pre>
+
 <p>The following is also not possible and results in an infinite loop that
 attempts to resolve <code>Process.name</code>.</p>
-<pre class="highlight text">&gt;&gt;&gt; Process(name = &#39;{{name}}&#39;).bind(name = &#39;installer&#39;)
-</pre>
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; Process(name = '{{name}}').bind(name = 'installer')
+</code></pre>
+
 <p>Do not confuse Structural attributes with bound Mustache variables.
 Attributes are implicitly converted to Mustache variables but not vice
 versa.</p>
@@ -881,25 +721,28 @@ often confused with it. This method is d
 Struct attributes to Mustache variables as described above.</p>
 
 <p>Suppose you create a Process object:</p>
-<pre class="highlight text">&gt;&gt;&gt; p = Process(name = &quot;process_one&quot;, cmdline = &quot;echo hello world&quot;)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; p = Process(name = "process_one", cmdline = "echo hello world")
 
 &gt;&gt;&gt; p
 Process(daemon=False, name=process_one, max_failures=1, ephemeral=False, min_duration=5,
         cmdline=echo hello world, final=False)
-</pre>
+</code></pre>
+
 <p>This <code>Process</code> object, &ldquo;<code>p</code>&rdquo;, can be used wherever a <code>Process</code> object is
 needed. It can also be reused by changing the value(s) of its
 attribute(s). Here we change its <code>name</code> attribute from <code>process_one</code> to
 <code>process_two</code>.</p>
-<pre class="highlight text">&gt;&gt;&gt; p(name = &quot;process_two&quot;)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; p(name = "process_two")
 Process(daemon=False, name=process_two, max_failures=1, ephemeral=False, min_duration=5,
         cmdline=echo hello world, final=False)
-</pre>
+</code></pre>
+
 <p>Template creation is a common use for this technique:</p>
-<pre class="highlight text">&gt;&gt;&gt; Daemon = Process(daemon = True)
-&gt;&gt;&gt; logrotate = Daemon(name = &#39;logrotate&#39;, cmdline = &#39;./logrotate conf/logrotate.conf&#39;)
-&gt;&gt;&gt; mysql = Daemon(name = &#39;mysql&#39;, cmdline = &#39;bin/mysqld --safe-mode&#39;)
-</pre>
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; Daemon = Process(daemon = True)
+&gt;&gt;&gt; logrotate = Daemon(name = 'logrotate', cmdline = './logrotate conf/logrotate.conf')
+&gt;&gt;&gt; mysql = Daemon(name = 'mysql', cmdline = 'bin/mysqld --safe-mode')
+</code></pre>
+
 <h3 id="advanced-binding">Advanced Binding</h3>
 
 <p>As described above, <code>.bind()</code> binds simple strings or numbers to
@@ -913,36 +756,41 @@ can also be bound via <code>.bind()</cod
 interchangeably (when &ldquo;<code>kwargs</code>&rdquo; is in a function definition, <code>kwargs</code>
 receives a Python dictionary containing all keyword arguments after the
 formal parameter list).</p>
-<pre class="highlight text">&gt;&gt;&gt; String(&#39;{{foo}}&#39;).bind(foo = &#39;bar&#39;) == String(&#39;{{foo}}&#39;).bind({&#39;foo&#39;: &#39;bar&#39;})
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; String('{{foo}}').bind(foo = 'bar') == String('{{foo}}').bind({'foo': 'bar'})
 True
-</pre>
+</code></pre>
+
 <p>Bindings done &ldquo;closer&rdquo; to the object in question take precedence:</p>
-<pre class="highlight text">&gt;&gt;&gt; p = Process(name = &#39;{{context}}_process&#39;)
-&gt;&gt;&gt; t = Task().bind(context = &#39;global&#39;)
-&gt;&gt;&gt; t(processes = [p, p.bind(context = &#39;local&#39;)])
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; p = Process(name = '{{context}}_process')
+&gt;&gt;&gt; t = Task().bind(context = 'global')
+&gt;&gt;&gt; t(processes = [p, p.bind(context = 'local')])
 Task(processes=ProcessList(
   Process(daemon=False, name=global_process, max_failures=1, ephemeral=False, final=False,
           min_duration=5),
   Process(daemon=False, name=local_process, max_failures=1, ephemeral=False, final=False,
           min_duration=5)
 ))
-</pre>
+</code></pre>
+
 <h4 id="binding-complex-objects">Binding Complex Objects</h4>
 
 <h5 id="lists">Lists</h5>
-<pre class="highlight text">&gt;&gt;&gt; fibonacci = List(Integer)([1, 1, 2, 3, 5, 8, 13])
-&gt;&gt;&gt; String(&#39;{{fib[4]}}&#39;).bind(fib = fibonacci)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; fibonacci = List(Integer)([1, 1, 2, 3, 5, 8, 13])
+&gt;&gt;&gt; String('{{fib[4]}}').bind(fib = fibonacci)
 String(5)
-</pre>
+</code></pre>
+
 <h5 id="maps">Maps</h5>
-<pre class="highlight text">&gt;&gt;&gt; first_names = Map(String, String)({&#39;Kent&#39;: &#39;Clark&#39;, &#39;Wayne&#39;: &#39;Bruce&#39;, &#39;Prince&#39;: &#39;Diana&#39;})
-&gt;&gt;&gt; String(&#39;{{first[Kent]}}&#39;).bind(first = first_names)
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; first_names = Map(String, String)({'Kent': 'Clark', 'Wayne': 'Bruce', 'Prince': 'Diana'})
+&gt;&gt;&gt; String('{{first[Kent]}}').bind(first = first_names)
 String(Clark)
-</pre>
+</code></pre>
+
 <h5 id="structurals">Structurals</h5>
-<pre class="highlight text">&gt;&gt;&gt; String(&#39;{{p.cmdline}}&#39;).bind(p = Process(cmdline = &quot;echo hello world&quot;))
+<pre class="highlight plaintext"><code>&gt;&gt;&gt; String('{{p.cmdline}}').bind(p = Process(cmdline = "echo hello world"))
 String(echo hello world)
-</pre>
+</code></pre>
+
 <h3 id="structural-binding">Structural Binding</h3>
 
 <p>Use structural templates when binding more than two or three individual
@@ -955,28 +803,28 @@ define a job profile. The following prof
 Distributed File System, to designate a file&rsquo;s location. <code>HDFS</code> does
 not come with Aurora, so you&rsquo;ll need to either install it separately
 or change the way the dataset is designated.</p>
-<pre class="highlight text">class Profile(Struct):
+<pre class="highlight plaintext"><code>class Profile(Struct):
   version = Required(String)
   environment = Required(String)
-  dataset = Default(String, hdfs://home/aurora/data/{{environment}}&#39;)
+  dataset = Default(String, hdfs://home/aurora/data/{{environment}}')
 
-PRODUCTION = Profile(version = &#39;live&#39;, environment = &#39;prod&#39;)
-DEVEL = Profile(version = &#39;latest&#39;,
-                environment = &#39;devel&#39;,
-                dataset = &#39;hdfs://home/aurora/data/test&#39;)
-TEST = Profile(version = &#39;latest&#39;, environment = &#39;test&#39;)
+PRODUCTION = Profile(version = 'live', environment = 'prod')
+DEVEL = Profile(version = 'latest',
+                environment = 'devel',
+                dataset = 'hdfs://home/aurora/data/test')
+TEST = Profile(version = 'latest', environment = 'test')
 
 JOB_TEMPLATE = Job(
-  name = &#39;application&#39;,
-  role = &#39;myteam&#39;,
-  cluster = &#39;cluster1&#39;,
-  environment = &#39;{{profile.environment}}&#39;,
+  name = 'application',
+  role = 'myteam',
+  cluster = 'cluster1',
+  environment = '{{profile.environment}}',
   task = SequentialTask(
-    name = &#39;task&#39;,
+    name = 'task',
     resources = Resources(cpu = 2, ram = 4*GB, disk = 8*GB),
     processes = [
-  Process(name = &#39;main&#39;, cmdline = &#39;java -jar application.jar -hdfsPath
-             {{profile.dataset}}&#39;)
+  Process(name = 'main', cmdline = 'java -jar application.jar -hdfsPath
+             {{profile.dataset}}')
     ]
    )
  )
@@ -986,7 +834,8 @@ jobs = [
   JOB_TEMPLATE.bind(profile = DEVEL),
   JOB_TEMPLATE.bind(profile = TEST),
  ]
-</pre>
+</code></pre>
+
 <p>In this case, a custom structural &ldquo;Profile&rdquo; is created to self-document
 the configuration to some degree. This also allows some schema
 &ldquo;type-checking&rdquo;, and for default self-substitution, e.g. in
@@ -1016,34 +865,35 @@ your configuration, it&rsquo;s likely an
 example below:</p>
 
 <p><code>redundant.aurora</code> contains:</p>
-<pre class="highlight text">download = Process(
-  name = &#39;download&#39;,
-  cmdline = &#39;wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2&#39;,
+<pre class="highlight plaintext"><code>download = Process(
+  name = 'download',
+  cmdline = 'wget http://www.python.org/ftp/python/2.7.3/Python-2.7.3.tar.bz2',
   max_failures = 5,
   min_duration = 1)
 
 unpack = Process(
-  name = &#39;unpack&#39;,
-  cmdline = &#39;rm -rf Python-2.7.3 &amp;&amp; tar xzf Python-2.7.3.tar.bz2&#39;,
+  name = 'unpack',
+  cmdline = 'rm -rf Python-2.7.3 &amp;&amp; tar xzf Python-2.7.3.tar.bz2',
   max_failures = 5,
   min_duration = 1)
 
 build = Process(
-  name = &#39;build&#39;,
-  cmdline = &#39;pushd Python-2.7.3 &amp;&amp; ./configure &amp;&amp; make &amp;&amp; popd&#39;,
+  name = 'build',
+  cmdline = 'pushd Python-2.7.3 &amp;&amp; ./configure &amp;&amp; make &amp;&amp; popd',
   max_failures = 1)
 
 email = Process(
-  name = &#39;email&#39;,
-  cmdline = &#39;echo Success | mail feynman@tmc.com&#39;,
+  name = 'email',
+  cmdline = 'echo Success | mail feynman@tmc.com',
   max_failures = 5,
   min_duration = 1)
 
 build_python = Task(
-  name = &#39;build_python&#39;,
+  name = 'build_python',
   processes = [download, unpack, build, email],
-  constraints = [Constraint(order = [&#39;download&#39;, &#39;unpack&#39;, &#39;build&#39;, &#39;email&#39;])])
-</pre>
+  constraints = [Constraint(order = ['download', 'unpack', 'build', 'email'])])
+</code></pre>
+
 <p>As you&rsquo;ll notice, there&rsquo;s a lot of repetition in the <code>Process</code>
 definitions. For example, almost every process sets a <code>max_failures</code>
 limit to 5 and a <code>min_duration</code> to 1. This is an opportunity for factoring
@@ -1054,66 +904,68 @@ bound via structural templating as descr
 section.</p>
 
 <p><code>less_redundant.aurora</code> contains:</p>
-<pre class="highlight text">class Python(Struct):
+<pre class="highlight plaintext"><code>class Python(Struct):
   version = Required(String)
-  base = Default(String, &#39;Python-{{version}}&#39;)
-  package = Default(String, &#39;{{base}}.tar.bz2&#39;)
+  base = Default(String, 'Python-{{version}}')
+  package = Default(String, '{{base}}.tar.bz2')
 
 ReliableProcess = Process(
   max_failures = 5,
   min_duration = 1)
 
 download = ReliableProcess(
-  name = &#39;download&#39;,
-  cmdline = &#39;wget http://www.python.org/ftp/python/{{python.version}}/{{python.package}}&#39;)
+  name = 'download',
+  cmdline = 'wget http://www.python.org/ftp/python/{{python.version}}/{{python.package}}')
 
 unpack = ReliableProcess(
-  name = &#39;unpack&#39;,
-  cmdline = &#39;rm -rf {{python.base}} &amp;&amp; tar xzf {{python.package}}&#39;)
+  name = 'unpack',
+  cmdline = 'rm -rf {{python.base}} &amp;&amp; tar xzf {{python.package}}')
 
 build = ReliableProcess(
-  name = &#39;build&#39;,
-  cmdline = &#39;pushd {{python.base}} &amp;&amp; ./configure &amp;&amp; make &amp;&amp; popd&#39;,
+  name = 'build',
+  cmdline = 'pushd {{python.base}} &amp;&amp; ./configure &amp;&amp; make &amp;&amp; popd',
   max_failures = 1)
 
 email = ReliableProcess(
-  name = &#39;email&#39;,
-  cmdline = &#39;echo Success | mail {{role}}@foocorp.com&#39;)
+  name = 'email',
+  cmdline = 'echo Success | mail {{role}}@foocorp.com')
 
 build_python = SequentialTask(
-  name = &#39;build_python&#39;,
-  processes = [download, unpack, build, email]).bind(python = Python(version = &quot;2.7.3&quot;))
-</pre>
+  name = 'build_python',
+  processes = [download, unpack, build, email]).bind(python = Python(version = "2.7.3"))
+</code></pre>
+
 <h3 id="thermos-uses-bash-but-thermos-is-not-bash">Thermos Uses bash, But Thermos Is Not bash</h3>
 
 <h4 id="bad">Bad</h4>
 
 <p>Many tiny Processes makes for harder to manage configurations.</p>
-<pre class="highlight text">copy = Process(
-  name = &#39;copy&#39;,
-  cmdline = &#39;rcp user@my_machine:my_application .&#39;
+<pre class="highlight plaintext"><code>copy = Process(
+  name = 'copy',
+  cmdline = 'rcp user@my_machine:my_application .'
  )
 
  unpack = Process(
-   name = &#39;unpack&#39;,
-   cmdline = &#39;unzip app.zip&#39;
+   name = 'unpack',
+   cmdline = 'unzip app.zip'
  )
 
  remove = Process(
-   name = &#39;remove&#39;,
-   cmdline = &#39;rm -f app.zip&#39;
+   name = 'remove',
+   cmdline = 'rm -f app.zip'
  )
 
  run = Process(
-   name = &#39;app&#39;,
-   cmdline = &#39;java -jar app.jar&#39;
+   name = 'app',
+   cmdline = 'java -jar app.jar'
  )
 
  run_task = Task(
    processes = [copy, unpack, remove, run],
    constraints = order(copy, unpack, remove, run)
  )
-</pre>
+</code></pre>
+
 <h4 id="good">Good</h4>
 
 <p>Each <code>cmdline</code> runs in a bash subshell, so you have the full power of
@@ -1123,21 +975,22 @@ thing to do.</p>
 <p>Also for Tasks that are simply a list of processes that run one after
 another, consider using the <code>SequentialTask</code> helper which applies a
 linear ordering constraint for you.</p>
-<pre class="highlight text">stage = Process(
-  name = &#39;stage&#39;,
-  cmdline = &#39;rcp user@my_machine:my_application . &amp;&amp; unzip app.zip &amp;&amp; rm -f app.zip&#39;)
+<pre class="highlight plaintext"><code>stage = Process(
+  name = 'stage',
+  cmdline = 'rcp user@my_machine:my_application . &amp;&amp; unzip app.zip &amp;&amp; rm -f app.zip')
 
-run = Process(name = &#39;app&#39;, cmdline = &#39;java -jar app.jar&#39;)
+run = Process(name = 'app', cmdline = 'java -jar app.jar')
 
 run_task = SequentialTask(processes = [stage, run])
-</pre>
+</code></pre>
+
 <h3 id="rarely-use-functions-in-your-configurations">Rarely Use Functions In Your Configurations</h3>
 
 <p>90% of the time you define a function in a <code>.aurora</code> file, you&rsquo;re
 probably Doing It Wrong&trade;.</p>
 
 <h4 id="bad">Bad</h4>
-<pre class="highlight text">def get_my_task(name, user, cpu, ram, disk):
+<pre class="highlight plaintext"><code>def get_my_task(name, user, cpu, ram, disk):
   return Task(
     name = name,
     user = user,
@@ -1146,9 +999,10 @@ probably Doing It Wrong&trade;.</p>
     resources = Resources(cpu = cpu, ram = ram, disk = disk)
  )
 
- task_one = get_my_task(&#39;task_one&#39;, &#39;feynman&#39;, 1.0, 32*MB, 1*GB)
- task_two = get_my_task(&#39;task_two&#39;, &#39;feynman&#39;, 2.0, 64*MB, 1*GB)
-</pre>
+ task_one = get_my_task('task_one', 'feynman', 1.0, 32*MB, 1*GB)
+ task_two = get_my_task('task_two', 'feynman', 2.0, 64*MB, 1*GB)
+</code></pre>
+
 <h4 id="good">Good</h4>
 
 <p>This one is more idiomatic. Forced keyword arguments prevents accidents,
@@ -1156,24 +1010,25 @@ e.g. constructing a task with &ldquo;32*
 disk. Less proliferation of task-construction techniques means
 easier-to-read, quicker-to-understand, and a more composable
 configuration.</p>
-<pre class="highlight text">TASK_TEMPLATE = SequentialTask(
-  user = &#39;wickman&#39;,
+<pre class="highlight plaintext"><code>TASK_TEMPLATE = SequentialTask(
+  user = 'wickman',
   processes = [STAGE_PROCESS, RUN_PROCESS],
 )
 
 task_one = TASK_TEMPLATE(
-  name = &#39;task_one&#39;,
+  name = 'task_one',
   resources = Resources(cpu = 1.0, ram = 32*MB, disk = 1*GB) )
 
 task_two = TASK_TEMPLATE(
-  name = &#39;task_two&#39;,
+  name = 'task_two',
   resources = Resources(cpu = 2.0, ram = 64*MB, disk = 1*GB)
 )
-</pre></div>
+</code></pre>
+
+</div>
 
   		</div>
   	  </div>
-	  
       	<div class="container-fluid section-footer buffer">
       <div class="container">
         <div class="row">
@@ -1198,5 +1053,6 @@ task_two = TASK_TEMPLATE(
         </div>
       </div>
     </div>
+
 	</body>
 </html>
\ No newline at end of file

Modified: aurora/site/publish/documentation/latest/contributing/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/latest/contributing/index.html?rev=1719617&r1=1719616&r2=1719617&view=diff
==============================================================================
--- aurora/site/publish/documentation/latest/contributing/index.html (original)
+++ aurora/site/publish/documentation/latest/contributing/index.html Sat Dec 12 01:46:48 2015
@@ -21,12 +21,11 @@
 	</script>
   </head>
   <body>
-	  
         <div class="container-fluid section-header">
   <div class="container">
     <div class="nav nav-bar">
     <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
-	<ul class="nav navbar-nav navbar-right">
+    <ul class="nav navbar-nav navbar-right">
       <li><a href="/documentation/latest/">Documentation</a></li>
       <li><a href="/community/">Community</a></li>
       <li><a href="/downloads/">Downloads</a></li>
@@ -34,7 +33,8 @@
     </ul>
     </div>
   </div>
-</div>	
+</div>
+	
   	  <div class="container-fluid">
   	  	<div class="container content">
           <div class="col-md-12 documentation">
@@ -42,8 +42,9 @@
 <h2 id="get-the-source-code">Get the Source Code</h2>
 
 <p>First things first, you&rsquo;ll need the source! The Aurora source is available from Apache git:</p>
-<pre class="highlight text">git clone https://git-wip-us.apache.org/repos/asf/aurora
-</pre>
+<pre class="highlight plaintext"><code>git clone https://git-wip-us.apache.org/repos/asf/aurora
+</code></pre>
+
 <h2 id="read-the-style-guides">Read the Style Guides</h2>
 
 <p>Aurora&rsquo;s codebase is primarily Java and Python and conforms to the Twitter Commons styleguides for
@@ -73,50 +74,57 @@ Subsequent runs will cache your login cr
 <h2 id="submitting-a-patch-for-review">Submitting a Patch for Review</h2>
 
 <p>Post a review with <code>rbt</code>, fill out the fields in your browser and hit Publish.</p>
-<pre class="highlight text">./rbt post -o
-</pre>
+<pre class="highlight plaintext"><code>./rbt post -o
+</code></pre>
+
+<p>If you&rsquo;re unsure about who to add as a reviewer, you can default to adding Bill Farner (wfarner) and
+Joshua Cohen (jcohen). They will take care of finding an appropriate reviewer for the patch.</p>
+
 <p>Once you&rsquo;ve done this, you probably want to mark the associated Jira issue as Reviewable.</p>
 
 <h2 id="updating-an-existing-review">Updating an Existing Review</h2>
 
 <p>Incorporate review feedback, make some more commits, update your existing review, fill out the
 fields in your browser and hit Publish.</p>
-<pre class="highlight text">./rbt post -o -r &lt;RB_ID&gt;
-</pre>
-<h2 id="merging-your-own-review-committers-">Merging Your Own Review (Committers)</h2>
+<pre class="highlight plaintext"><code>./rbt post -o -r &lt;RB_ID&gt;
+</code></pre>
+
+<h2 id="merging-your-own-review-committers">Merging Your Own Review (Committers)</h2>
 
 <p>Once you have shipits from the right committers, merge your changes in a single commit and mark
 the review as submitted. The typical workflow is:</p>
-<pre class="highlight text">git checkout master
+<pre class="highlight plaintext"><code>git checkout master
 git pull origin master
 ./rbt patch -c &lt;RB_ID&gt;  # Verify the automatically-generated commit message looks sane,
                         # editing if necessary.
 git show master         # Verify everything looks sane
 git push origin master
 ./rbt close &lt;RB_ID&gt;
-</pre>
+</code></pre>
+
 <p>Note that even if you&rsquo;re developing using feature branches you will not use <code>git merge</code> - each
 commit will be an atomic change accompanied by a ReviewBoard entry.</p>
 
 <h2 id="merging-someone-else-39-s-review">Merging Someone Else&rsquo;s Review</h2>
 
 <p>Sometimes you&rsquo;ll need to merge someone else&rsquo;s RB. The typical workflow for this is</p>
-<pre class="highlight text">git checkout master
+<pre class="highlight plaintext"><code>git checkout master
 git pull origin master
 ./rbt patch -c &lt;RB_ID&gt;
 git show master  # Verify everything looks sane, author is correct
 git push origin master
-</pre>
+</code></pre>
+
 <h2 id="cleaning-up">Cleaning Up</h2>
 
 <p>Your patch has landed, congratulations! The last thing you&rsquo;ll want to do before moving on to your
 next fix is to clean up your Jira and Reviewboard. The former of which should be marked as
 &ldquo;Resolved&rdquo; while the latter should be marked as &ldquo;Submitted&rdquo;.</p>
+
 </div>
 
   		</div>
   	  </div>
-	  
       	<div class="container-fluid section-footer buffer">
       <div class="container">
         <div class="row">
@@ -141,5 +149,6 @@ next fix is to clean up your Jira and Re
         </div>
       </div>
     </div>
+
 	</body>
 </html>
\ No newline at end of file

Modified: aurora/site/publish/documentation/latest/cron-jobs/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/latest/cron-jobs/index.html?rev=1719617&r1=1719616&r2=1719617&view=diff
==============================================================================
--- aurora/site/publish/documentation/latest/cron-jobs/index.html (original)
+++ aurora/site/publish/documentation/latest/cron-jobs/index.html Sat Dec 12 01:46:48 2015
@@ -21,12 +21,11 @@
 	</script>
   </head>
   <body>
-	  
         <div class="container-fluid section-header">
   <div class="container">
     <div class="nav nav-bar">
     <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
-	<ul class="nav navbar-nav navbar-right">
+    <ul class="nav navbar-nav navbar-right">
       <li><a href="/documentation/latest/">Documentation</a></li>
       <li><a href="/community/">Community</a></li>
       <li><a href="/downloads/">Downloads</a></li>
@@ -34,7 +33,8 @@
     </ul>
     </div>
   </div>
-</div>	
+</div>
+	
   	  <div class="container-fluid">
   	  	<div class="container content">
           <div class="col-md-12 documentation">
@@ -79,22 +79,23 @@ include &ldquo;every 5 minutes&rdquo; (<
 &ldquo;the 1st and 15th day of the month at 03:00&rdquo; (<code>0 3 1,15 *</code>).</p>
 
 <p>Example (available in the <a href="/documentation/latest/vagrant/">Vagrant environment</a>):</p>
-<pre class="highlight text">$ cat /vagrant/examples/job/cron_hello_world.aurora
+<pre class="highlight plaintext"><code>$ cat /vagrant/examples/job/cron_hello_world.aurora
 # cron_hello_world.aurora
 # A cron job that runs every 5 minutes.
 jobs = [
   Job(
-    cluster = &#39;devcluster&#39;,
-    role = &#39;www-data&#39;,
-    environment = &#39;test&#39;,
-    name = &#39;cron_hello_world&#39;,
-    cron_schedule = &#39;*/5 * * * *&#39;,
+    cluster = 'devcluster',
+    role = 'www-data',
+    environment = 'test',
+    name = 'cron_hello_world',
+    cron_schedule = '*/5 * * * *',
     task = SimpleTask(
-      &#39;cron_hello_world&#39;,
-      &#39;echo &quot;Hello world from cron, the time is now $(date --rfc-822)&quot;&#39;),
+      'cron_hello_world',
+      'echo "Hello world from cron, the time is now $(date --rfc-822)"'),
   ),
 ]
-</pre>
+</code></pre>
+
 <h2 id="collision-policies">Collision Policies</h2>
 
 <p>The <code>cron_collision_policy</code> field specifies the scheduler&rsquo;s behavior when a new cron job is
@@ -118,7 +119,7 @@ grow faster than they can process it.</p
 
 <p>Unlike with services, which aurora will always re-execute regardless of exit status, instances of
 cron jobs retry according to the <code>max_task_failures</code> attribute of the
-<a href="configuration-reference.md#task-objects">Task</a> object. To get &ldquo;run-until-failure&rdquo; semantics,
+<a href="configuration-reference.md#task-objects">Task</a> object. To get &ldquo;run-until-success&rdquo; semantics,
 set <code>max_task_failures</code> to <code>-1</code>.</p>
 
 <h2 id="interacting-with-cron-jobs-via-the-aurora-cli">Interacting with cron jobs via the Aurora CLI</h2>
@@ -130,18 +131,21 @@ for up-to-date usage instructions.</p>
 
 <p>Schedules a new cron job on the Aurora cluster for later runs or replaces the existing cron template
 with a new one. Only future runs will be affected, any existing active tasks are left intact.</p>
-<pre class="highlight text">$ aurora cron schedule devcluster/www-data/test/cron_hello_world /vagrant/examples/jobs/cron_hello_world.aurora
-</pre>
+<pre class="highlight plaintext"><code>$ aurora cron schedule devcluster/www-data/test/cron_hello_world /vagrant/examples/jobs/cron_hello_world.aurora
+</code></pre>
+
 <h3 id="cron-deschedule">cron deschedule</h3>
 
 <p>Deschedules a cron job, preventing future runs but allowing current runs to complete.</p>
-<pre class="highlight text">$ aurora cron deschedule devcluster/www-data/test/cron_hello_world
-</pre>
+<pre class="highlight plaintext"><code>$ aurora cron deschedule devcluster/www-data/test/cron_hello_world
+</code></pre>
+
 <h3 id="cron-start">cron start</h3>
 
 <p>Start a cron job immediately, outside of its normal cron schedule.</p>
-<pre class="highlight text">$ aurora cron start devcluster/www-data/test/cron_hello_world
-</pre>
+<pre class="highlight plaintext"><code>$ aurora cron start devcluster/www-data/test/cron_hello_world
+</code></pre>
+
 <h3 id="job-killall-job-restart-job-kill">job killall, job restart, job kill</h3>
 
 <p>Cron jobs create instances running on the cluster that you can interact with like normal Aurora
@@ -184,11 +188,11 @@ attempting to kill the old one (outside
 
 <p>Cron timezone is configured indepdendently of JVM timezone with the <code>-cron_timezone</code> flag and
 defaults to UTC.</p>
+
 </div>
 
   		</div>
   	  </div>
-	  
       	<div class="container-fluid section-footer buffer">
       <div class="container">
         <div class="row">
@@ -213,5 +217,6 @@ defaults to UTC.</p>
         </div>
       </div>
     </div>
+
 	</body>
 </html>
\ No newline at end of file

Modified: aurora/site/publish/documentation/latest/deploying-aurora-scheduler/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/latest/deploying-aurora-scheduler/index.html?rev=1719617&r1=1719616&r2=1719617&view=diff
==============================================================================
--- aurora/site/publish/documentation/latest/deploying-aurora-scheduler/index.html (original)
+++ aurora/site/publish/documentation/latest/deploying-aurora-scheduler/index.html Sat Dec 12 01:46:48 2015
@@ -21,12 +21,11 @@
 	</script>
   </head>
   <body>
-	  
         <div class="container-fluid section-header">
   <div class="container">
     <div class="nav nav-bar">
     <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
-	<ul class="nav navbar-nav navbar-right">
+    <ul class="nav navbar-nav navbar-right">
       <li><a href="/documentation/latest/">Documentation</a></li>
       <li><a href="/community/">Community</a></li>
       <li><a href="/downloads/">Downloads</a></li>
@@ -34,7 +33,8 @@
     </ul>
     </div>
   </div>
-</div>	
+</div>
+	
   	  <div class="container-fluid">
   	  	<div class="container content">
           <div class="col-md-12 documentation">
@@ -60,6 +60,8 @@ machines.  This guide helps you get the
 <li><a href="#storage-performance-considerations">Storage Performance Considerations</a></li>
 <li><a href="#network-considerations">Network considerations</a></li>
 <li><a href="#considerations-for-running-jobs-in-docker">Considerations for running jobs in docker</a></li>
+<li><a href="#security-considerations">Security Considerations</a></li>
+<li><a href="#configuring-resource-oversubscription">Configuring Resource Oversubscription</a></li>
 </ul></li>
 <li><a href="#running-aurora">Running Aurora</a>
 
@@ -74,6 +76,11 @@ machines.  This guide helps you get the
 <li><a href="#example">Example</a></li>
 </ul></li>
 </ul></li>
+<li><a href="#best-practices">Best practices</a>
+
+<ul>
+<li><a href="#diversity">Diversity</a></li>
+</ul></li>
 <li><a href="#common-problems">Common problems</a>
 
 <ul>
@@ -83,9 +90,12 @@ machines.  This guide helps you get the
 <li><a href="#scheduler-not-registered">Scheduler not registered</a></li>
 <li><a href="#symptoms-1">Symptoms</a></li>
 <li><a href="#solution-1">Solution</a></li>
-<li><a href="#tasks-are-stuck-in-pending-forever">Tasks are stuck in PENDING forever</a></li>
-<li><a href="#symptoms-2">Symptoms</a></li>
-<li><a href="#solution-2">Solution</a></li>
+</ul></li>
+<li><a href="#changing-scheduler-quorum-size">Changing Scheduler Quorum Size</a>
+
+<ul>
+<li><a href="#preparation">Preparation</a></li>
+<li><a href="#adding-new-schedulers">Adding New Schedulers</a></li>
 </ul></li>
 </ul>
 
@@ -93,32 +103,34 @@ machines.  This guide helps you get the
 
 <p>The Aurora scheduler is a standalone Java server. As part of the build process it creates a bundle
 of all its dependencies, with the notable exceptions of the JVM and libmesos. Each target server
-should have a JVM (Java 7 or higher) and libmesos (0.21.1) installed.</p>
+should have a JVM (Java 7 or higher) and libmesos (0.23.0) installed.</p>
 
-<h3 id="creating-the-distribution-zip-file-optional-">Creating the Distribution .zip File (Optional)</h3>
+<h3 id="creating-the-distribution-zip-file-optional">Creating the Distribution .zip File (Optional)</h3>
 
 <p>To create a distribution for installation you will need build tools installed. On Ubuntu this can be
 done with <code>sudo apt-get install build-essential default-jdk</code>.</p>
-<pre class="highlight text">git clone http://git-wip-us.apache.org/repos/asf/aurora.git
+<pre class="highlight plaintext"><code>git clone http://git-wip-us.apache.org/repos/asf/aurora.git
 cd aurora
 ./gradlew distZip
-</pre>
+</code></pre>
+
 <p>Copy the generated <code>dist/distributions/aurora-scheduler-*.zip</code> to each node that will run a scheduler.</p>
 
 <h3 id="installing-aurora">Installing Aurora</h3>
 
 <p>Extract the aurora-scheduler zip file. The example configurations assume it is extracted to
 <code>/usr/local/aurora-scheduler</code>.</p>
-<pre class="highlight text">sudo unzip dist/distributions/aurora-scheduler-*.zip -d /usr/local
-sudo ln -nfs &quot;$(ls -dt /usr/local/aurora-scheduler-* | head -1)&quot; /usr/local/aurora-scheduler
-</pre>
+<pre class="highlight plaintext"><code>sudo unzip dist/distributions/aurora-scheduler-*.zip -d /usr/local
+sudo ln -nfs "$(ls -dt /usr/local/aurora-scheduler-* | head -1)" /usr/local/aurora-scheduler
+</code></pre>
+
 <h2 id="configuring-aurora">Configuring Aurora</h2>
 
 <h3 id="a-note-on-configuration">A Note on Configuration</h3>
 
 <p>Like Mesos, Aurora uses command-line flags for runtime configuration. As such the Aurora
 &ldquo;configuration file&rdquo; is typically a <code>scheduler.sh</code> shell script of the form.</p>
-<pre class="highlight shell"><span class="c">#!/bin/bash</span>
+<pre class="highlight shell"><code><span class="c">#!/bin/bash</span>
 <span class="nv">AURORA_HOME</span><span class="o">=</span>/usr/local/aurora-scheduler
 
 <span class="c"># Flags controlling the JVM.</span>
@@ -139,14 +151,16 @@ sudo ln -nfs &quot;$(ls -dt /usr/local/a
 <span class="nb">export </span><span class="nv">GLOG_v</span><span class="o">=</span>1
 <span class="nb">export </span><span class="nv">LIBPROCESS_PORT</span><span class="o">=</span>8083
 
-<span class="nv">JAVA_OPTS</span><span class="o">=</span><span class="s2">&quot;</span><span class="k">${</span><span class="nv">JAVA_OPTS</span><span class="p">[*]</span><span class="k">}</span><span class="s2">&quot;</span> <span class="nb">exec</span> <span class="s2">&quot;</span><span class="nv">$AURORA_HOME</span><span class="s2">/bin/aurora-scheduler&quot;</span> <span class="s2">&quot;</span><span class="k">${</span><span class="nv">AURORA_FLAGS</span><span class="p">[@]</span><span class="k">}</span><span class="s2">&quot;</span>
-</pre>
+<span class="nv">JAVA_OPTS</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">JAVA_OPTS</span><span class="p">[*]</span><span class="k">}</span><span class="s2">"</span> <span class="nb">exec</span> <span class="s2">"</span><span class="nv">$AURORA_HOME</span><span class="s2">/bin/aurora-scheduler"</span> <span class="s2">"</span><span class="k">${</span><span class="nv">AURORA_FLAGS</span><span class="p">[@]</span><span class="k">}</span><span class="s2">"</span>
+</code></pre>
+
 <p>That way Aurora&rsquo;s current flags are visible in <code>ps</code> and in the <code>/vars</code> admin endpoint.</p>
 
 <p>Examples are available under <code>examples/scheduler/</code>. For a list of available Aurora flags and their
 documentation run</p>
-<pre class="highlight text">/usr/local/aurora-scheduler/bin/aurora-scheduler -help
-</pre>
+<pre class="highlight plaintext"><code>/usr/local/aurora-scheduler/bin/aurora-scheduler -help
+</code></pre>
+
 <h3 id="replicated-log-configuration">Replicated Log Configuration</h3>
 
 <p>All Aurora state is persisted to a replicated log. This includes all jobs Aurora is running
@@ -195,12 +209,14 @@ log and storage configuration options.</
 <h2 id="initializing-the-replicated-log">Initializing the Replicated Log</h2>
 
 <p>Before you start Aurora you will also need to initialize the log on a majority of the masters.</p>
-<pre class="highlight text">mesos-log initialize --path=&quot;/path/to/native/log&quot;
-</pre>
+<pre class="highlight plaintext"><code>mesos-log initialize --path="/path/to/native/log"
+</code></pre>
+
 <p>The <code>--path</code> flag should match the <code>--native_log_file_path</code> flag to the scheduler.
 Failing to do this will result the following message when you try to start the scheduler.</p>
-<pre class="highlight text">Replica in EMPTY status received a broadcasted recover request
-</pre>
+<pre class="highlight plaintext"><code>Replica in EMPTY status received a broadcasted recover request
+</code></pre>
+
 <h3 id="storage-performance-considerations">Storage Performance Considerations</h3>
 
 <p>See <a href="/documentation/latest/scheduler-storage/">this document</a> for scheduler storage performance considerations.</p>
@@ -211,7 +227,7 @@ Failing to do this will result the follo
 and a libprocess (HTTP+Protobuf) port used to communicate with the Mesos master and for the log
 replication protocol. These can be left unconfigured (the scheduler publishes all selected ports
 to ZooKeeper) or explicitly set in the startup script as follows:</p>
-<pre class="highlight text"># ...
+<pre class="highlight plaintext"><code># ...
 AURORA_FLAGS=(
   # ...
   -http_port=8081
@@ -220,7 +236,8 @@ AURORA_FLAGS=(
 # ...
 export LIBPROCESS_PORT=8083
 # ...
-</pre>
+</code></pre>
+
 <h3 id="considerations-for-running-jobs-in-docker-containers">Considerations for running jobs in docker containers</h3>
 
 <p><em>Note: Docker support is currently EXPERIMENTAL.</em></p>
@@ -255,10 +272,30 @@ out or returns anything other than <code
 restarted.</p>
 
 <p>For example, monit can be configured with</p>
-<pre class="highlight text">if failed port 8081 send &quot;GET /health HTTP/1.0\r\n&quot; expect &quot;OK\n&quot; with timeout 2 seconds for 10 cycles then restart
-</pre>
+<pre class="highlight plaintext"><code>if failed port 8081 send "GET /health HTTP/1.0\r\n" expect "OK\n" with timeout 2 seconds for 10 cycles then restart
+</code></pre>
+
 <p>assuming you set <code>-http_port=8081</code>.</p>
 
+<h2 id="security-considerations">Security Considerations</h2>
+
+<p>See <a href="/documentation/latest/security/">security.md</a>.</p>
+
+<h2 id="configuring-resource-oversubscription">Configuring Resource Oversubscription</h2>
+
+<p><strong>WARNING</strong>: This feature is currently in alpha status. Do not use it in production clusters!
+See <a href="configuration-reference.md#revocable-jobs">this document</a> for more feature details.</p>
+
+<p>Set these scheduler flag to allow receiving revocable Mesos offers:</p>
+<pre class="highlight plaintext"><code>-receive_revocable_resources=true
+</code></pre>
+
+<p>Specify a tier configuration file path:</p>
+<pre class="highlight plaintext"><code>-tier_config=path/to/tiers/config.json
+</code></pre>
+
+<p>Example <a href="../src/test/resources/org/apache/aurora/scheduler/tiers-example.json">tier configuration file</a>.</p>
+
 <h3 id="maintaining-an-aurora-installation">Maintaining an Aurora Installation</h3>
 
 <h3 id="monitoring">Monitoring</h3>
@@ -281,6 +318,9 @@ constraints are arbitrary and available
 <code>dedicated</code> attribute.  Aurora treats this specially, and only allows matching jobs to run on these
 machines, and will only schedule matching jobs on these machines.</p>
 
+<p>See the <a href="resources.md#resource-quota">section</a> about resource quotas to learn how quotas apply to
+dedicated jobs.</p>
+
 <h5 id="syntax">Syntax</h5>
 
 <p>The dedicated attribute has semantic meaning. The format is <code>$role(/.*)?</code>. When a job is created,
@@ -292,22 +332,40 @@ enforce this.</p>
 <h5 id="example">Example</h5>
 
 <p>Consider the following slave command line:</p>
-<pre class="highlight text">mesos-slave --attributes=&quot;host:$HOST;rack:$RACK;dedicated:db_team/redis&quot; ...
-</pre>
+<pre class="highlight plaintext"><code>mesos-slave --attributes="dedicated:db_team/redis" ...
+</code></pre>
+
 <p>And this job configuration:</p>
-<pre class="highlight text">Service(
-  name = &#39;redis&#39;,
-  role = &#39;db_team&#39;,
+<pre class="highlight plaintext"><code>Service(
+  name = 'redis',
+  role = 'db_team',
   constraints = {
-    &#39;dedicated&#39;: &#39;db_team/redis&#39;
+    'dedicated': 'db_team/redis'
   }
   ...
 )
-</pre>
+</code></pre>
+
 <p>The job configuration is indicating that it should only be scheduled on slaves with the attribute
 <code>dedicated:db_team/redis</code>.  Additionally, Aurora will prevent any tasks that do <em>not</em> have that
 constraint from running on those slaves.</p>
 
+<h2 id="best-practices">Best practices</h2>
+
+<h3 id="diversity">Diversity</h3>
+
+<p>Data centers are often organized with hierarchical failure domains.  Common failure domains
+include hosts, racks, rows, and PDUs.  If you have this information available, it is wise to tag
+the mesos-slave with them as
+<a href="https://mesos.apache.org/documentation/attributes-resources/">attributes</a>.</p>
+
+<p>When it comes time to schedule jobs, Aurora will automatically spread them across the failure
+domains as specified in the
+<a href="configuration-reference.md#specifying-scheduling-constraints">job configuration</a>.</p>
+
+<p>Note: in virtualized environments like EC2, the only attribute that usually makes sense for this
+purpose is <code>host</code>.</p>
+
 <h2 id="common-problems">Common problems</h2>
 
 <p>So you&rsquo;ve started your first cluster and are running into some issues? We&rsquo;ve collected some common
@@ -321,11 +379,12 @@ stumbling blocks and solutions here to h
 <li>Scheduler RPCs and web interface claim <code>Storage is not READY</code></li>
 <li>Scheduler log repeatedly prints messages like</li>
 </ul>
-<pre class="highlight text">  I1016 16:12:27.234133 26081 replica.cpp:638] Replica in EMPTY status
+<pre class="highlight plaintext"><code>  I1016 16:12:27.234133 26081 replica.cpp:638] Replica in EMPTY status
   received a broadcasted recover request
   I1016 16:12:27.234256 26084 recover.cpp:188] Received a recover response
   from a replica in EMPTY status
-</pre>
+</code></pre>
+
 <h4 id="solution">Solution</h4>
 
 <p>When you create a new cluster, you need to inform a quorum of schedulers that they are safe to
@@ -338,36 +397,43 @@ of multiple simultaneous disk failures o
 <h4 id="symptoms">Symptoms</h4>
 
 <p>Scheduler log contains</p>
-<pre class="highlight text">Framework has not been registered within the tolerated delay.
-</pre>
+<pre class="highlight plaintext"><code>Framework has not been registered within the tolerated delay.
+</code></pre>
+
 <h4 id="solution">Solution</h4>
 
 <p>Double-check that the scheduler is configured correctly to reach the master. If you are registering
 the master in ZooKeeper, make sure command line argument to the master:</p>
-<pre class="highlight text">--zk=zk://$ZK_HOST:2181/mesos/master
-</pre>
+<pre class="highlight plaintext"><code>--zk=zk://$ZK_HOST:2181/mesos/master
+</code></pre>
+
 <p>is the same as the one on the scheduler:</p>
-<pre class="highlight text">-mesos_master_address=zk://$ZK_HOST:2181/mesos/master
-</pre>
-<h3 id="tasks-are-stuck-in-pending-forever">Tasks are stuck in <code>PENDING</code> forever</h3>
+<pre class="highlight plaintext"><code>-mesos_master_address=zk://$ZK_HOST:2181/mesos/master
+</code></pre>
 
-<h4 id="symptoms">Symptoms</h4>
+<h2 id="changing-scheduler-quorum-size">Changing Scheduler Quorum Size</h2>
 
-<p>The scheduler is registered, and (receiving offers](docs/monitoring.md#scheduler<em>resource</em>offers),
-but tasks are perpetually shown as <code>PENDING - Constraint not satisfied: host</code>.</p>
+<p>Special care needs to be taken when changing the size of the Aurora scheduler quorum.
+Since Aurora uses a Mesos replicated log, similar steps need to be followed as when
+<a href="http://mesos.apache.org/documentation/latest/operational-guide">changing the mesos quorum size</a>.</p>
 
-<h4 id="solution">Solution</h4>
+<h3 id="preparation">Preparation</h3>
+
+<p>Increase <a href="storage-config.md#-native_log_quorum_size">-native<em>log</em>quorum_size</a> on each
+existing scheduler and restart them. When updating from 3 to 5 schedulers, the quorum size
+would grow from 2 to 3.</p>
 
-<p>Check that your slaves are configured with <code>host</code> and <code>rack</code> attributes.  Aurora requires that
-slaves are tagged with these two common failure domains to ensure that it can safely place tasks
-such that jobs are resilient to failure.</p>
+<h3 id="adding-new-schedulers">Adding New Schedulers</h3>
+
+<p>Start the new schedulers with <code>-native_log_quorum_size</code> set to the new value. Failing to
+first increase the quorum size on running schedulers can in some cases result in corruption
+or truncating of the replicated log used by Aurora. In that case, see the documentation on
+<a href="storage-config.md#recovering-from-a-scheduler-backup">recovering from backup</a>.</p>
 
-<p>See our <a href="examples/vagrant/upstart/mesos-slave.conf">vagrant example</a> for details.</p>
 </div>
 
   		</div>
   	  </div>
-	  
       	<div class="container-fluid section-footer buffer">
       <div class="container">
         <div class="row">
@@ -392,5 +458,6 @@ such that jobs are resilient to failure.
         </div>
       </div>
     </div>
+
 	</body>
 </html>
\ No newline at end of file

Modified: aurora/site/publish/documentation/latest/developing-aurora-client/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/latest/developing-aurora-client/index.html?rev=1719617&r1=1719616&r2=1719617&view=diff
==============================================================================
--- aurora/site/publish/documentation/latest/developing-aurora-client/index.html (original)
+++ aurora/site/publish/documentation/latest/developing-aurora-client/index.html Sat Dec 12 01:46:48 2015
@@ -21,12 +21,11 @@
 	</script>
   </head>
   <body>
-	  
         <div class="container-fluid section-header">
   <div class="container">
     <div class="nav nav-bar">
     <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
-	<ul class="nav navbar-nav navbar-right">
+    <ul class="nav navbar-nav navbar-right">
       <li><a href="/documentation/latest/">Documentation</a></li>
       <li><a href="/community/">Community</a></li>
       <li><a href="/downloads/">Downloads</a></li>
@@ -34,7 +33,8 @@
     </ul>
     </div>
   </div>
-</div>	
+</div>
+	
   	  <div class="container-fluid">
   	  	<div class="container content">
           <div class="col-md-12 documentation">
@@ -58,7 +58,7 @@ how the client locates this file can be
 are:</p>
 
 <ul>
-<li>Build a client executable: <code>./pants binary src/main/python/apache/aurora/client/cli:aurora</code></li>
+<li>Build a client executable: <code>./pants binary src/main/python/apache/aurora/client:aurora</code></li>
 <li>Test client code: <code>./pants test src/test/python/apache/aurora/client/cli:all</code></li>
 </ul>
 
@@ -69,30 +69,33 @@ To start a virtual cluster, you need to
 the aurora workspace. This will create a vagrant host named &ldquo;devcluster&rdquo;, with a mesos master, a set
 of mesos slaves, and an aurora scheduler.</p>
 
-<p>If you have changed you would like to test in your local cluster, you&rsquo;ll rebuild the client:</p>
-<pre class="highlight text">vagrant ssh -c &#39;aurorabuild client&#39;
-</pre>
+<p>If you have a change you would like to test in your local cluster, you&rsquo;ll rebuild the client:</p>
+<pre class="highlight plaintext"><code>vagrant ssh -c 'aurorabuild client'
+</code></pre>
+
 <p>Once this completes, the <code>aurora</code> command will reflect your changes.</p>
 
 <h1 id="running-debugging-the-client-in-pycharm">Running/Debugging the Client in PyCharm</h1>
 
 <p>It&rsquo;s possible to use PyCharm to run and debug both the client and client tests in an IDE. In order
 to do this, first run:</p>
-<pre class="highlight text">build-support/python/make-pycharm-virtualenv
-</pre>
+<pre class="highlight plaintext"><code>build-support/python/make-pycharm-virtualenv
+</code></pre>
+
 <p>This script will configure a virtualenv with all of our Python requirements. Once the script
 completes it will emit instructions for configuring PyCharm:</p>
-<pre class="highlight text">Your PyCharm environment is now set up.  You can open the project root
+<pre class="highlight plaintext"><code>Your PyCharm environment is now set up.  You can open the project root
 directory with PyCharm.
 
 Once the project is loaded:
   - open project settings
-  - click &#39;Project Interpreter&#39;
+  - click 'Project Interpreter'
   - click the cog in the upper-right corner
-  - click &#39;Add Local&#39;
-  - select &#39;build-support/python/pycharm.venv/bin/python&#39;
-  - click &#39;OK&#39;
-</pre>
+  - click 'Add Local'
+  - select 'build-support/python/pycharm.venv/bin/python'
+  - click 'OK'
+</code></pre>
+
 <h3 id="running-debugging-tests">Running/Debugging Tests</h3>
 
 <p>After following these instructions, you should now be able to run/debug tests directly from the IDE
@@ -126,11 +129,11 @@ is the directory where our example clust
 <h1 id="making-thrift-schema-changes">Making thrift schema changes</h1>
 
 <p>See <a href="/documentation/latest/thrift-deprecation/">this document</a> for any thrift related changes.</p>
+
 </div>
 
   		</div>
   	  </div>
-	  
       	<div class="container-fluid section-footer buffer">
       <div class="container">
         <div class="row">
@@ -155,5 +158,6 @@ is the directory where our example clust
         </div>
       </div>
     </div>
+
 	</body>
 </html>
\ No newline at end of file

Modified: aurora/site/publish/documentation/latest/developing-aurora-scheduler/index.html
URL: http://svn.apache.org/viewvc/aurora/site/publish/documentation/latest/developing-aurora-scheduler/index.html?rev=1719617&r1=1719616&r2=1719617&view=diff
==============================================================================
--- aurora/site/publish/documentation/latest/developing-aurora-scheduler/index.html (original)
+++ aurora/site/publish/documentation/latest/developing-aurora-scheduler/index.html Sat Dec 12 01:46:48 2015
@@ -21,12 +21,11 @@
 	</script>
   </head>
   <body>
-	  
         <div class="container-fluid section-header">
   <div class="container">
     <div class="nav nav-bar">
     <a href="/"><img src="/assets/img/aurora_logo_dkbkg.svg" width="300" alt="Transparent Apache Aurora logo with dark background"/></a>
-	<ul class="nav navbar-nav navbar-right">
+    <ul class="nav navbar-nav navbar-right">
       <li><a href="/documentation/latest/">Documentation</a></li>
       <li><a href="/community/">Community</a></li>
       <li><a href="/downloads/">Downloads</a></li>
@@ -34,7 +33,8 @@
     </ul>
     </div>
   </div>
-</div>	
+</div>
+	
   	  <div class="container-fluid">
   	  	<div class="container content">
           <div class="col-md-12 documentation">
@@ -44,35 +44,41 @@
 <h1 id="getting-started">Getting Started</h1>
 
 <p>You will need Java 7 installed and on your <code>PATH</code> or unzipped somewhere with <code>JAVA_HOME</code> set. Then</p>
-<pre class="highlight text">./gradlew tasks
-</pre>
+<pre class="highlight plaintext"><code>./gradlew tasks
+</code></pre>
+
 <p>will bootstrap the build system and show available tasks. This can take a while the first time you
 run it but subsequent runs will be much faster due to cached artifacts.</p>
 
 <h2 id="running-the-tests">Running the Tests</h2>
 
 <p>Aurora has a comprehensive unit test suite. To run the tests use</p>
-<pre class="highlight text">./gradlew build
-</pre>
+<pre class="highlight plaintext"><code>./gradlew build
+</code></pre>
+
 <p>Gradle will only re-run tests when dependencies of them have changed. To force a re-run of all
 tests use</p>
-<pre class="highlight text">./gradlew clean build
-</pre>
+<pre class="highlight plaintext"><code>./gradlew clean build
+</code></pre>
+
 <h2 id="running-the-build-with-code-quality-checks">Running the build with code quality checks</h2>
 
 <p>To speed up development iteration, the plain gradle commands will not run static analysis tools.
 However, you should run these before posting a review diff, and <strong>always</strong> run this before pushing a
 commit to origin/master.</p>
-<pre class="highlight text">./gradlew build -Pq
-</pre>
+<pre class="highlight plaintext"><code>./gradlew build -Pq
+</code></pre>
+
 <h2 id="creating-a-bundle-for-deployment">Creating a bundle for deployment</h2>
 
 <p>Gradle can create a zip file containing Aurora, all of its dependencies, and a launch script with</p>
-<pre class="highlight text">./gradlew distZip
-</pre>
+<pre class="highlight plaintext"><code>./gradlew distZip
+</code></pre>
+
 <p>or a tar file containing the same files with</p>
-<pre class="highlight text">./gradlew distTar
-</pre>
+<pre class="highlight plaintext"><code>./gradlew distTar
+</code></pre>
+
 <p>The output file will be written to <code>dist/distributions/aurora-scheduler.zip</code> or
 <code>dist/distributions/aurora-scheduler.tar</code>.</p>
 
@@ -81,43 +87,67 @@ commit to origin/master.</p>
 <h2 id="setting-up-an-ide">Setting up an IDE</h2>
 
 <p>Gradle can generate project files for your IDE. To generate an IntelliJ IDEA project run</p>
-<pre class="highlight text">./gradlew idea
-</pre>
+<pre class="highlight plaintext"><code>./gradlew idea
+</code></pre>
+
 <p>and import the generated <code>aurora.ipr</code> file.</p>
 
 <h2 id="adding-or-upgrading-a-dependency">Adding or Upgrading a Dependency</h2>
 
 <p>New dependencies can be added from Maven central by adding a <code>compile</code> dependency to <code>build.gradle</code>.
 For example, to add a dependency on <code>com.example</code>&rsquo;s <code>example-lib</code> 1.0 add this block:</p>
-<pre class="highlight text">compile &#39;com.example:example-lib:1.0&#39;
-</pre>
+<pre class="highlight plaintext"><code>compile 'com.example:example-lib:1.0'
+</code></pre>
+
 <p>NOTE: Anyone thinking about adding a new dependency should first familiarize themself with the
 Apache Foundation&rsquo;s third-party licensing
 <a href="http://www.apache.org/legal/resolved.html#category-x">policy</a>.</p>
 
 <h1 id="developing-aurora-ui">Developing Aurora UI</h1>
 
-<h2 id="installing-bower-optional-">Installing bower (optional)</h2>
+<h2 id="installing-bower-optional">Installing bower (optional)</h2>
 
 <p>Third party JS libraries used in Aurora (located at 3rdparty/javascript/bower_components) are
 managed by bower, a JS dependency manager. Bower is only required if you plan to add, remove or
 update JS libraries. Bower can be installed using the following command:</p>
-<pre class="highlight text">npm install -g bower
-</pre>
+<pre class="highlight plaintext"><code>npm install -g bower
+</code></pre>
+
 <p>Bower depends on node.js and npm. The easiest way to install node on a mac is via brew:</p>
-<pre class="highlight text">brew install node
-</pre>
+<pre class="highlight plaintext"><code>brew install node
+</code></pre>
+
 <p>For more node.js installation options refer to <a href="https://github.com/joyent/node/wiki/Installation">https://github.com/joyent/node/wiki/Installation</a>.</p>
 
 <p>More info on installing and using bower can be found at: <a href="http://bower.io/">http://bower.io/</a>. Once installed, you can
 use the following commands to view and modify the bower repo at
 3rdparty/javascript/bower_components</p>
-<pre class="highlight text">bower list
+<pre class="highlight plaintext"><code>bower list
 bower install &lt;library name&gt;
 bower remove &lt;library name&gt;
 bower update &lt;library name&gt;
 bower help
-</pre>
+</code></pre>
+
+<h2 id="faster-iteration-in-vagrant">Faster Iteration in Vagrant</h2>
+
+<p>The scheduler serves UI assets from the classpath. For production deployments this means the assets
+are served from within a jar. However, for faster development iteration, the vagrant image is
+configured to add <code>/vagrant/dist/resources/main</code> to the head of CLASSPATH. This path is configured
+as a shared filesystem to the path on the host system where your Aurora repository lives. This means
+that any updates to dist/resources/main in your checkout will be reflected immediately in the UI
+served from within the vagrant image.</p>
+
+<p>The one caveat to this is that this path is under <code>dist</code> not <code>src</code>. This is because the assets must
+be processed by gradle before they can be served. So, unfortunately, you cannot just save your local
+changes and see them reflected in the UI, you must first run <code>./gradlew processResources</code>. This is
+less than ideal, but better than having to restart the scheduler after every change. Additionally,
+gradle makes this process somewhat easier with the use of the <code>--continuous</code> flag. If you run:
+<code>./gradlew processResources --continuous</code> gradle will monitor the filesystem for changes and run the
+task automatically as necessary. This doesn&rsquo;t quite provide hot-reload capabilities, but it does
+allow for &lt;5s from save to changes being visibile in the UI with no further action required on the
+part of the developer.</p>
+
 <h1 id="developing-the-aurora-build-system">Developing the Aurora Build System</h1>
 
 <h2 id="bootstrapping-gradle">Bootstrapping Gradle</h2>
@@ -125,22 +155,23 @@ bower help
 <p>The following files were autogenerated by <code>gradle wrapper</code> using gradle 1.8&rsquo;s
 <a href="http://www.gradle.org/docs/1.8/dsl/org.gradle.api.tasks.wrapper.Wrapper.html">Wrapper</a> plugin and
 should not be modified directly:</p>
-<pre class="highlight text">./gradlew
+<pre class="highlight plaintext"><code>./gradlew
 ./gradlew.bat
 ./gradle/wrapper/gradle-wrapper.jar
 ./gradle/wrapper/gradle-wrapper.properties
-</pre>
+</code></pre>
+
 <p>To upgrade Gradle unpack the new version somewhere, run <code>/path/to/new/gradle wrapper</code> in the
 repository root and commit the changed files.</p>
 
 <h1 id="making-thrift-schema-changes">Making thrift schema changes</h1>
 
 <p>See <a href="/documentation/latest/thrift-deprecation/">this document</a> for any thrift related changes.</p>
+
 </div>
 
   		</div>
   	  </div>
-	  
       	<div class="container-fluid section-footer buffer">
       <div class="container">
         <div class="row">
@@ -165,5 +196,6 @@ repository root and commit the changed f
         </div>
       </div>
     </div>
+
 	</body>
 </html>
\ No newline at end of file



Mime
View raw message