forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			95 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| Execution Model
 | |
| ===============
 | |
| This document describes the execution model of the Normandy Client.
 | |
| 
 | |
| The basic unit of instruction from the server is a *recipe*, which contains
 | |
| instructions for filtering, and arguments for a given action. See below for
 | |
| details.
 | |
| 
 | |
| One iteration through all of these steps is called a *Normandy session*. This
 | |
| happens at least once every 6 hours, and possibly more often if Remote
 | |
| Settings syncs new changes.
 | |
| 
 | |
| 1. Fetching
 | |
| -----------
 | |
| A list of all active recipes is retrieved from Remote Settings, which has
 | |
| likely been syncing them in the background.
 | |
| 
 | |
| 2. Suitability
 | |
| --------------
 | |
| 
 | |
| Once recipes have been retrieved, they go through several checks to determine
 | |
| their suitability for this client. Recipes contain information about which
 | |
| clients should execute the recipe. All recipes are processed by all clients,
 | |
| and all filtering happens in the client.
 | |
| 
 | |
| For more information, see `the suitabilities docs <./suitabilities.html>`_.
 | |
| 
 | |
| Signature
 | |
| ~~~~~~~~~
 | |
| 
 | |
| First, recipes are validated using a signature generated by Autograph_ that
 | |
| is included with the recipe. This signature validates both the contents of
 | |
| the recipe as well as its source.
 | |
| 
 | |
| This signature is separate and distinct from the signing that happens on the
 | |
| Remote Settings collection. This provides additional assurance that this
 | |
| recipe is legitimate and intended to run on this client.
 | |
| 
 | |
| .. _Autograph: https://github.com/mozilla-services/autograph
 | |
| 
 | |
| Capabilities
 | |
| ~~~~~~~~~~~~
 | |
| Next a recipe is checked for compatibility using *capabilities*.
 | |
| Capabilities are simple strings, such as ``"action:show-heartbeat"``. A
 | |
| recipe contains a list of required capabilities, and the Normandy Client has
 | |
| a list of capabilities that it supports. If any of the capabilities required
 | |
| by the recipe are not compatible with the client, then the recipe does not
 | |
| execute.
 | |
| 
 | |
| Capabilities are used to avoid running recipes on a client that are so
 | |
| incompatible as to be harmful. For example, some changes to filter expression
 | |
| handling cannot be detected by filter expressions, and so older clients that
 | |
| receive filters using these new features would break.
 | |
| 
 | |
| .. note::
 | |
| 
 | |
|     Capabilities were first introduced in Firefox 70. Clients prior to this
 | |
|     do not check capabilities, and run all recipes provided. To accommodate
 | |
|     this, the server splits recipes into two Remote Settings collections,
 | |
|     ``normandy-recipes``, and ``normandy-recipes-capabilities``. Clients
 | |
|     prior to Firefox 70 use the former, whereas Firefox 70 and above use the
 | |
|     latter. Recipes that only require "baseline" capabilities are published
 | |
|     to both, and those that require advanced capabilities are only published
 | |
|     to the capabilities aware collection.
 | |
| 
 | |
| Filter Expressions
 | |
| ~~~~~~~~~~~~~~~~~~
 | |
| Finally the recipe's filter expression is checked. Filter expressions are
 | |
| written in an expression language named JEXL_ that is similar to JavaScript,
 | |
| but far simpler. It is intended to be as safe to evaluate as possible.
 | |
| 
 | |
| .. _JEXL: https://github.com/mozilla/mozjexl
 | |
| 
 | |
| Filters are evaluated in a context that contains details about the client
 | |
| including browser versions, installed add-ons, and Telemetry data. Filters
 | |
| have access to "transforms" which are simple functions that can do things like
 | |
| check preference values or parse strings into ``Date`` objects. Filters don't
 | |
| have access to change any state in the browser, and are generally
 | |
| idempotent. However, filters are *not* considered to be "pure functions",
 | |
| because they have access to state that may change, such as time and location.
 | |
| 
 | |
| 3. Execution
 | |
| ------------
 | |
| After a recipe's suitability is determined, that recipe is executed. The
 | |
| recipe specifies an *action* by name, as well as arguments to pass to that
 | |
| action. The arguments are validated against an expected schema.
 | |
| 
 | |
| All action have a pre- and post-step that runs once each Normandy session.
 | |
| The pre-step is run before any recipes are executed, and once the post-step
 | |
| is executed, no more recipes will be executed on that action in this session.
 | |
| 
 | |
| Each recipe is passed to the action, along with its suitability. Individual
 | |
| actions have their own semantics about what to do with recipes. Many actions
 | |
| maintain their own life cycle of events for new recipes, existing recipes,
 | |
| and recipes that stop applying to this client.
 | 
