| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1"> |
| <title>Apache Aurora</title> |
| <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"> |
| <link href="/assets/css/main.css" rel="stylesheet"> |
| <!-- Analytics --> |
| <script type="text/javascript"> |
| var _gaq = _gaq || []; |
| _gaq.push(['_setAccount', 'UA-45879646-1']); |
| _gaq.push(['_setDomainName', 'apache.org']); |
| _gaq.push(['_trackPageview']); |
| |
| (function() { |
| var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; |
| ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
| var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); |
| })(); |
| </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"> |
| <li><a href="/documentation/latest/">Documentation</a></li> |
| <li><a href="/community/">Community</a></li> |
| <li><a href="/downloads/">Downloads</a></li> |
| <li><a href="/blog/">Blog</a></li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| |
| <div class="container-fluid"> |
| <div class="container content"> |
| <div class="col-md-12 documentation"> |
| <h5 class="page-header text-uppercase">Documentation |
| <select onChange="window.location.href='/documentation/' + this.value + '/clientv2/'" |
| value="0.5.0-incubating"> |
| <option value="0.22.0" |
| > |
| 0.22.0 |
| (latest) |
| </option> |
| <option value="0.21.0" |
| > |
| 0.21.0 |
| </option> |
| <option value="0.20.0" |
| > |
| 0.20.0 |
| </option> |
| <option value="0.19.1" |
| > |
| 0.19.1 |
| </option> |
| <option value="0.19.0" |
| > |
| 0.19.0 |
| </option> |
| <option value="0.18.1" |
| > |
| 0.18.1 |
| </option> |
| <option value="0.18.0" |
| > |
| 0.18.0 |
| </option> |
| <option value="0.17.0" |
| > |
| 0.17.0 |
| </option> |
| <option value="0.16.0" |
| > |
| 0.16.0 |
| </option> |
| <option value="0.15.0" |
| > |
| 0.15.0 |
| </option> |
| <option value="0.14.0" |
| > |
| 0.14.0 |
| </option> |
| <option value="0.13.0" |
| > |
| 0.13.0 |
| </option> |
| <option value="0.12.0" |
| > |
| 0.12.0 |
| </option> |
| <option value="0.11.0" |
| > |
| 0.11.0 |
| </option> |
| <option value="0.10.0" |
| > |
| 0.10.0 |
| </option> |
| <option value="0.9.0" |
| > |
| 0.9.0 |
| </option> |
| <option value="0.8.0" |
| > |
| 0.8.0 |
| </option> |
| <option value="0.7.0-incubating" |
| > |
| 0.7.0-incubating |
| </option> |
| <option value="0.6.0-incubating" |
| > |
| 0.6.0-incubating |
| </option> |
| <option value="0.5.0-incubating" |
| selected="selected"> |
| 0.5.0-incubating |
| </option> |
| </select> |
| </h5> |
| <h1 id="aurora-client-v2">Aurora Client v2</h1> |
| |
| <h2 id="overview">Overview</h2> |
| |
| <p>Our goal is to replace the current Aurora command-line client. The |
| current client suffers from an early monolithic structure, and a long |
| development history of rapid unplanned evolution.</p> |
| |
| <p>In addition to its internal problems, the current Aurora client is |
| confusing for users. There are several different kinds of objects |
| manipulated by the Aurora command line, and the difference between |
| them is often not clear. (What’s the difference between a job and a |
| configuration?) For each type of object, there are different commands, |
| and it’s hard to remember which command should be used for which kind |
| of object.</p> |
| |
| <p>Instead of continuing to let the Aurora client develop and evolve |
| randomly, it’s time to take a principled look at the Aurora command |
| line, and figure out how to make our command line processing make |
| sense. At the same time, the code needs to be cleaned up, and divided |
| into small comprehensible units based on a plugin architecture.</p> |
| |
| <p>Doing this now will give us a more intuitive, consistent, and easy to |
| use client, as well as a sound platform for future development.</p> |
| |
| <h2 id="goals">Goals</h2> |
| |
| <ul> |
| <li>A command line tool for interacting with Aurora that is easy for |
| users to understand.</li> |
| <li>A noun/verb command model.</li> |
| <li>A modular source-code architecture.</li> |
| <li>Non-disruptive transition for users.</li> |
| </ul> |
| |
| <h2 id="non-goals">Non-Goals</h2> |
| |
| <ul> |
| <li>The most important non-goal is that we’re not trying to redesign the |
| Aurora scheduler, the Aurora executor, or any of the peripheral tools |
| that the Aurora command line interacts with; we only want to create a |
| better command line client.</li> |
| <li>We do not want to change thermos, mesos, hadoop, etc.</li> |
| <li>We do not want to create new objects that users will work with to |
| interact with Mesos or Aurora.</li> |
| <li>We do not want to change Aurora job configuration files or file formats.</li> |
| <li>We do not want to change the Aurora API.</li> |
| <li>We don’t want to boil the ocean: there are many things that we could |
| include in the scope of this project, but we don’t want to be |
| distracted by re-implementing all of twitter.commons in order to |
| create a perfect Aurora client.</li> |
| </ul> |
| |
| <h2 id="background">Background</h2> |
| |
| <p>Aurora is a system that’s used to run and manage services and |
| service-like jobs running in a datacenter. Aurora takes care of |
| allocating resources in order to schedule and run jobs without |
| requiring teams to manage dedicated hardware. The heart of Aurora is |
| called the scheduler, and is responsible for finding and assigning |
| resources to tasks.</p> |
| |
| <p>The Aurora scheduler provides a thrift API. The scheduler API is |
| low-level and difficult to interact with. Users do not interact |
| directly with the Aurora API; instead, they use a command-line tool, |
| which provides a collection of easy-to-use commands. This command-line |
| tool, in turn, talks to the scheduler API to launch and manage jobs in |
| datacenter clusters. The command-line tool is called the Aurora |
| client.</p> |
| |
| <p>The current implementation of the Aurora client is haphazard, |
| and really needs to be cleaned up:</p> |
| |
| <ul> |
| <li>The code is monolithic and hard to maintain. It’s implemented using |
| <code>twitter.common.app</code>, which assumes that all of the command code lives |
| in a single source file. To work around this, and allow some |
| subdivision, it uses a hack of <code>twitter.common.app</code> to force |
| registration of commands from multiple modules. It’s hard to |
| understand, and hard to modify.</li> |
| <li>The current code is very difficult to test. Because of the way it’s |
| built, there is no consistent way of passing key application data |
| around. As a result, each unit test of client operations needs a |
| difficult-to-assemble custom setup of mock objects.</li> |
| <li>The current code handles errors poorly, and it is difficult to |
| fix. Many common errors produce unacceptable results. For example, |
| issuing an unknown command generates an error message “main takes 0 |
| parameters but received 1”; passing an invalid parameter to other |
| commands frequently produces a stack trace.</li> |
| <li>The current command line is confusing for users. There are several |
| different kinds of objects manipulated by the Aurora command line, |
| and the difference between them is often not entirely clear. (What’s |
| the difference between a job and a configuration?) |
| For each type of object, there are different |
| commands, and it’s frequently not clear just which command should be |
| used for which object.</li> |
| </ul> |
| |
| <p>Instead of continuing to let it develop and evolve randomly, it’s time |
| to take a principled look at the Aurora command line, and figure out |
| how to make command line processing make sense. At the same time, the |
| code needs to be cleaned up, and divided into small comprehensible |
| units based on a plugin architecture.</p> |
| |
| <h2 id="requirements">Requirements</h2> |
| |
| <p>Aurora is aimed at engineers who run jobs and services in a |
| datacenter. As a result, the requirements for the aurora client are |
| all engineering focused:</p> |
| |
| <ul> |
| <li><strong>Consistency</strong>: commands should follow a consistent structure, so that |
| users can apply knowledge and intuition gained from working with |
| some aurora commands to new commands. This means that when commands |
| can re-use the same options, they should; that objects should be |
| referred to by consistent syntax throughout the tool.</li> |
| <li><strong>Helpfulness</strong>: commands should be structured so that the system can |
| generate helpful error messages. If a user just runs “aurora”, they |
| should get a basic usage message. If they try to run an invalid |
| command, they should get a message that the command is invalid, not |
| a stack dump or “command main() takes 0 parameters but received |
| 2”. Commands should not generate extraneous output that obscures the |
| key facts that the user needs to know, and the default behavior of |
| commands should not generate outputs that will be routinely ignored |
| by users.</li> |
| <li><strong>Extensibility</strong>: it should be easy to plug in new commands, |
| including custom commands, to adapt the Aurora client to new |
| environments.</li> |
| <li><strong>Script-friendly command output</strong>: every command should at least include |
| an option that generates output that’s script-friendly. Scripts should be |
| able to work with command-output without needing to do screen scraping.</li> |
| <li><strong>Scalability</strong>: the tools should be usable for any foreseeable size |
| of Aurora datacenters and machine clusters.</li> |
| </ul> |
| |
| <h2 id="design-overview">Design Overview</h2> |
| |
| <p>The Aurora client will be reimplemented using a noun-verb model, |
| similar to the cmdlet model used by Monad/Windows Powershell. Users |
| will work by providing a noun for the type of object being operated |
| on, and a verb for the specific operation being performed on the |
| object, followed by parameters. For example, to create a job, the user |
| would execute: “<code>aurora job create smfd/mchucarroll/devel/jobname |
| job.aurora</code>”. The noun is <code>job</code> and the verb is <code>create</code>.</p> |
| |
| <p>The client will be implemented following that noun-verb |
| convention. Each noun will be a separate component, which can be |
| registered into the command-line framework. Each verb will be |
| implemented by a class that registers with the appropriate noun. Nouns |
| and verbs will each provide methods that add their command line |
| options and parameters to the options parser, using the Python |
| argparse library.</p> |
| |
| <h2 id="detailed-design">Detailed Design</h2> |
| |
| <h3 id="interface">Interface</h3> |
| |
| <p>In this section, we’ll walk through the types of objects that the |
| client can manipulate, and the operations that need to be provided for |
| each object. These form the primary interface that engineers will use |
| to interact with Aurora.</p> |
| |
| <p>In the command-line, each of the object types will have an Aurora |
| subcommand. The commands to manipulate the object type will follow the |
| type. For example, here are several commands in the old syntax |
| contrasted against the new noun/verb syntax.</p> |
| |
| <ul> |
| <li>Get quota for a role: |
| |
| <ul> |
| <li>Noun/Verb syntax: <code>aurora quota get west/www-data</code></li> |
| <li>Old syntax: <code>aurora get_quota --cluster=smf1 www-data</code></li> |
| </ul></li> |
| <li>Create job: |
| |
| <ul> |
| <li>Noun/Verb syntax: <code>aurora job create west/www-data/test/job job.aurora</code></li> |
| <li>Old syntax: <code>aurora create west/www-data/test/job job.aurora</code></li> |
| </ul></li> |
| <li>Schedule a job to run at a specific interval: |
| |
| <ul> |
| <li>Noun/verb: <code>aurora cron schedule east/www-data/test/job job.aurora</code></li> |
| <li>Old: <code>aurora create east/www-data/test/job job.aurora</code></li> |
| </ul></li> |
| </ul> |
| |
| <p>As you can see in these examples, the new syntax is more consistent: |
| you always specify the cluster where a command executes as part of an |
| identifier, where in the old syntax, it was sometimes part of the |
| jobkey and sometimes specified with a “–cluster” option.</p> |
| |
| <p>The new syntax is also more clear and explicit: even without knowing |
| much about Aurora, it’s clear what objects each command is acting on, |
| where in the old syntax, commands like “create” are unclear.</p> |
| |
| <h3 id="the-job-noun">The Job Noun</h3> |
| |
| <p>A job is a configured program ready to run in Aurora. A job is, |
| conceptually, a task factory: when a job is submitted to the Aurora |
| scheduler, it creates a collection of tasks. The job contains a |
| complete description of everything it needs to create a collection of |
| tasks. (Note that this subsumes “service” commands. A service is just |
| a task whose configuration sets the is_service flag, so we don’t have |
| separate commands for working with services.) Jobs are specified using |
| <code>cluster/role/env/name</code> jobkey syntax.</p> |
| |
| <ul> |
| <li><code>aurora job create *jobkey* *config*</code>: submits a job to a cluster, launching the task(s) specified by the job config.</li> |
| <li><code>aurora job status *jobkey*</code>: query job status. Prints information about the job, |
| whether it’s running, etc., to standard out. If jobkey includes |
| globs, it should list all jobs that match the glob</li> |
| <li><code>aurora job kill *jobkey*/*instanceids*</code>: kill/stop some of a jobs instances. This stops a job’ tasks; if the job |
| has service tasks, they’ll be disabled, so that they won’t restart.</li> |
| <li><code>aurora job killall *jobkey*</code>: kill all of the instances of a job. This |
| is distinct from the <em>kill</em> command as a safety measure: omitting the |
| instances from a kill command shouldn’t result in destroying the entire job.</li> |
| <li><code>aurora job restart *jobkey*</code>: conceptually, this will kill a job, and then |
| launch it again. If the job does not exist, then fail with an error |
| message. In fact, the underlying implementation does the |
| kill/relaunch on a rolling basis - so it’s not an immediate kill of |
| all shards/instances, followed by a delay as all instances relaunch, |
| but rather a controlled gradual process.</li> |
| <li><code>aurora job list *jobkey*</code>: list all jobs that match the jobkey spec that are |
| registered with the scheduler. This will include both jobs that are |
| currently running, and jobs that are scheduled to run at a later |
| time. The job key can be partial: if it specifies cluster, all jobs |
| on the cluster will be listed; cluster/role, all jobs running on the cluster under the role will be listed, etc.</li> |
| </ul> |
| |
| <h2 id="the-schedule-noun-cron">The Schedule Noun (Cron)</h2> |
| |
| <p>Note (3/21/2014): The “cron” noun is <em>not</em> implemented yet.</p> |
| |
| <p>Cron is a scheduler adjunct that periodically runs a job on a |
| schedule. The cron commands all manipulate cron schedule entries. The |
| schedules are specified as a part of the job configuration.</p> |
| |
| <ul> |
| <li><code>aurora cron schedule jobkey config</code>: schedule a job to run by cron.</li> |
| <li><code>aurora cron deschedule jobkey</code>: removes a jobs entry from the cron schedule.</li> |
| <li><code>aurora cron status jobkey</code>: query for a scheduled job’s status.</li> |
| </ul> |
| |
| <h2 id="the-quota-noun">The Quota Noun</h2> |
| |
| <p>A quota is a data object maintained by the scheduler that specifies the maximum |
| resources that may be consumed by jobs owned by a particular role. In the future, |
| we may add new quota types. At some point, we’ll also probably add an administrators |
| command to set quotas.</p> |
| |
| <ul> |
| <li><code>aurora quota get *cluster/role*</code></li> |
| </ul> |
| |
| <h2 id="implementation">Implementation</h2> |
| |
| <p>The current command line is monolithic. Every command on an Aurora |
| object is a top-level command in the Aurora client. In the |
| restructured command line, each of the primary object types |
| manipulated by Aurora should have its own sub-command.</p> |
| |
| <ul> |
| <li>Advantages of this approach: |
| |
| <ul> |
| <li>Easier to detangle the command-line processing. The top-level |
| command-processing will be a small set of subcommand |
| processors. Option processing for each subcommand can be offloaded |
| to a separate module.</li> |
| <li>The aurora top-level help command will be much more |
| comprehensible. Instead of giving a huge list of every possible |
| command, it will present the list of top-level object types, and |
| then users can request help on the commands for a specific type |
| of object.</li> |
| <li>The sub-commands can be separated into distinct command-line |
| tools when appropriate.</li> |
| </ul></li> |
| </ul> |
| |
| <h3 id="command-structure-and-options-processing">Command Structure and Options Processing</h3> |
| |
| <p>The implementation will follow closely on Pants goals. Pants goals use |
| a static registration system to add new subcommands. In pants, each |
| goal command is an implementation of a command interface, and provides |
| implementations of methods to register options and parameters, and to |
| actually execute the command. In this design, commands are modular and |
| easy to implement, debug, and combine in different ways.</p> |
| |
| <p>For the Aurora client, we plan to use a two-level variation of the |
| basic concept from pants. At the top-level we will have nouns. A noun |
| will define some common command-line parameters required by all of its |
| verbs, and will provide a registration hook for attaching verbs. Nouns |
| will be implemented as a subclass of a basic Noun type.</p> |
| |
| <p>Each verb will, similarly, be implemented as a subclass of Verb. Verbs |
| will be able to specify command-line options and parameters.</p> |
| |
| <p>Both <code>Noun</code> and <code>Verb</code> will be subclasses of a common base-class <code>AuroraCommand</code>:</p> |
| <pre class="highlight objective_c"><code><span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">AuroraCommand</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">get_options</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""Gets the set of command-line options objects for this command.</span><span style="color: #a61717;background-color: #e3d2d2"> |
| </span><span style="color: #d14"> The result is a list of CommandOption objects.</span><span style="color: #a61717;background-color: #e3d2d2"> |
| </span><span style="color: #d14"> """</span> |
| <span style="background-color: #f8f8f8">pass</span> |
| |
| <span style="color: #000000;font-weight: bold">@property</span> |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">help</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""Returns the help message for this command"""</span> |
| |
| <span style="color: #000000;font-weight: bold">@property</span> |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">usage</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""Returns a short usage description of the command"""</span> |
| |
| <span style="color: #000000;font-weight: bold">@property</span> |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">name</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""Returns the command name"""</span> |
| </code></pre> |
| |
| <p>A command-line tool will be implemented as an instance of a <code>CommandLine</code>:</p> |
| <pre class="highlight objective_c"><code><span style="background-color: #f8f8f8">class</span> <span style="background-color: #f8f8f8">CommandLine</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">object</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""The top-level object implementing a command-line application."""</span> |
| |
| <span style="color: #000000;font-weight: bold">@property</span> |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">name</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""Returns the name of this command-line tool"""</span> |
| |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">print_out</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">str</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="background-color: #f8f8f8">print</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">str</span><span style="background-color: #f8f8f8">)</span> |
| |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">print_err</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">str</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="background-color: #f8f8f8">print</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">str</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">file</span><span style="color: #000000;font-weight: bold">=</span><span style="background-color: #f8f8f8">sys</span><span style="background-color: #f8f8f8">.</span><span style="background-color: #f8f8f8">stderr</span><span style="background-color: #f8f8f8">)</span> |
| |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">register_noun</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">noun</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""Adds a noun to the application"""</span> |
| |
| <span style="background-color: #f8f8f8">def</span> <span style="background-color: #f8f8f8">register_plugin</span><span style="background-color: #f8f8f8">(</span><span style="background-color: #f8f8f8">self</span><span style="background-color: #f8f8f8">,</span> <span style="background-color: #f8f8f8">plugin</span><span style="background-color: #f8f8f8">)</span><span style="color: #000000;font-weight: bold">:</span> |
| <span style="color: #d14">"""Adds a configuration plugin to the system"""</span> |
| </code></pre> |
| |
| <p>Nouns are registered into a command-line using the <code>register_noun</code> |
| method. They are weakly coupled to the application, making it easy to |
| use a single noun in several different command-line tools. Nouns allow |
| the registration of verbs using the <code>register_verb</code> method.</p> |
| |
| <p>When commands execute, they’re given an instance of a <em>context object</em>. |
| The context object must be an instance of a subclass of <code>AuroraCommandContext</code>. |
| Options, parameters, and IO are all accessed using the context object. The context |
| is created dynamically by the noun object owning the verb being executed. Developers |
| are strongly encouraged to implement custom contexts for their nouns, and move functionality |
| shared by the noun’s verbs into the context object. The context interface is:</p> |
| <pre class="highlight plaintext"><code>class Context(object): |
| class Error(Exception): pass |
| |
| class ArgumentException(Error): pass |
| |
| class CommandError(Error): |
| |
| @classmethod |
| def exit(cls, code, msg): |
| """Exit the application with an error message""" |
| raise cls.CommandError(code, msg) |
| |
| def print_out(self, msg, indent=0): |
| """Prints a message to standard out, with an indent""" |
| |
| def print_err(self, msg, indent=0): |
| """Prints a message to standard err, with an indent""" |
| </code></pre> |
| |
| <p>In addition to nouns and verbs, there’s one more kind of registerable |
| component, called a <em>configuration plugin</em>. These objects add a set of |
| command-line options that can be passed to <em>all</em> of the commands |
| implemented in the tool. Before the command is executed, the |
| configuration plugin will be invoked, and will process its |
| command-line arguments. This is useful for general configuration |
| changes, like establish a secure tunnel to talk to machines in a |
| datacenter. (A useful way to think of a plugin is as something like an |
| aspect that can be woven in to aurora to provide environment-specific |
| configuration.) A configuration plugin is implemented as an instance |
| of class <code>ConfigurationPlugin</code>, and registered with the |
| <code>register_plugin</code> method of the <code>CommandLine</code> object. The interface of |
| a plugin is:</p> |
| <pre class="highlight plaintext"><code>class ConfigurationPlugin(object): |
| """A component that can be plugged in to a command-line.""" |
| |
| @abstractmethod |
| def get_options(self): |
| """Return the set of options processed by this plugin""" |
| |
| @abstractmethod |
| def execute(self, context): |
| """Run the context/command line initialization code for this plugin.""" |
| </code></pre> |
| |
| <h3 id="command-execution">Command Execution</h3> |
| |
| <p>The options process and command execution is built as a facade over Python’s |
| standard argparse. All of the actual argument processing is done by the |
| argparse library.</p> |
| |
| <p>Once the options are processed, the framework will start to execute the command. Command execution consists of:</p> |
| |
| <h1 id="create-a-context-object-the-framework-will-use-the-argparse-options-to-identify">Create a context object. The framework will use the argparse options to identify</h1> |
| |
| <p>which noun is being invoked, and will call that noun’s <code>create_context</code> method. |
| The argparse options object will be stored in the context.</p> |
| |
| <h1 id="execute-any-configuration-plugins-before-any-command-is-invoked-the-framework">Execute any configuration plugins. Before any command is invoked, the framework</h1> |
| |
| <p>will first iterate over all of the registered configuration plugins. For each |
| plugin, it will invoke the <code>execute</code> method.</p> |
| |
| <h1 id="the-noun-will-use-the-context-to-find-out-what-verb-is-being-invoked-and-it-will">The noun will use the context to find out what verb is being invoked, and it will</h1> |
| |
| <p>then call that verb’s <code>execute</code> method.</p> |
| |
| <h1 id="the-command-will-exit-its-return-code-will-be-whatever-was-returned-by-the-verb-39-s">The command will exit. Its return code will be whatever was returned by the verb’s</h1> |
| |
| <p><code>execute</code> method.</p> |
| |
| <p>Commands are expected to return a code from a list of standard exit codes, |
| which can be found in <code>src/main/python/apache/aurora/client/cli/__init__.py</code>.</p> |
| |
| </div> |
| |
| </div> |
| </div> |
| <div class="container-fluid section-footer buffer"> |
| <div class="container"> |
| <div class="row"> |
| <div class="col-md-2 col-md-offset-1"><h3>Quick Links</h3> |
| <ul> |
| <li><a href="/downloads/">Downloads</a></li> |
| <li><a href="/community/">Mailing Lists</a></li> |
| <li><a href="http://issues.apache.org/jira/browse/AURORA">Issue Tracking</a></li> |
| <li><a href="/documentation/latest/contributing/">How To Contribute</a></li> |
| </ul> |
| </div> |
| <div class="col-md-2"><h3>The ASF</h3> |
| <ul> |
| <li><a href="http://www.apache.org/licenses/">License</a></li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li> |
| <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li> |
| <li><a href="http://www.apache.org/security/">Security</a></li> |
| </ul> |
| </div> |
| <div class="col-md-6"> |
| <p class="disclaimer">© 2014-2017 <a href="http://www.apache.org/">Apache Software Foundation</a>. Licensed under the <a href="http://www.apache.org/licenses/">Apache License v2.0</a>. The <a href="https://www.flickr.com/photos/trondk/12706051375/">Aurora Borealis IX photo</a> displayed on the homepage is available under a <a href="https://creativecommons.org/licenses/by-nc-nd/2.0/">Creative Commons BY-NC-ND 2.0 license</a>. Apache, Apache Aurora, and the Apache feather logo are trademarks of The Apache Software Foundation.</p> |
| </div> |
| </div> |
| </div> |
| |
| </body> |
| </html> |