Closed Bug 1436129 Opened 3 years ago Closed 2 years ago

[Meta] Implement actions internal to the client, instead of fetching from normandy-server


(Firefox :: Normandy Client, enhancement, P3)




Tracking Status
firefox60 --- affected


(Reporter: mythmon, Unassigned)



(Keywords: meta)

Currently, when executing a recipe the action code is fetched by name from the server. In very simplified code it goes something like this:

for (recipe in recipes) {
  const action = await fetchActionByName(recipe.action);
  const actionImplementation = fetch(action.implementationUrl);
  const sandbox = new Sandbox();
  sandbox.cloneIntoGlobal("recipe", recipe);
  sandbox.eval("new Action().exec(recipe)");

The reality is a lot more complicated, but this outlines the idea well. There is a lot of extra complexity to safely execute the code by running it in a Sandbox. It is hard to reason about, and hard to modify. The equivalent execution in the new model looks something like this (again, extremely simplified):

for (recipe in recipes) {
  let action = actions[recipe.action];
  if (!action) {
    log.warn(`Unknown action type ${recipe.action}`);


The current execution model is structured this way to allow for faster changes to actions. In theory they can be updated quickly on the server without having to ride the trains. In practice, most changes to actions require changes to the client, which ride the trains. We also expected more actions to exist, written against a standardized Driver API. In practice, we only have a few actions, and most of the work is done in the the Driver API instead of in the actions. For example, the action opt-out-study is 85 lines. AddonStudies.jsm, which is exposed via the Driver, is 350 lines.

Finally, actions being implemented this way worked well when we we had multiple clients implementing the Driver API: when the self-repair shim was still active. Since we stopped using the self-repair shim over a year ago, we haven't introduced or planned to introduce any new clients.

This bug covers

* Reimplementing actions in the Normandy Client
* Removing the Driver
* Removing the sandbox, where appropriate
* Removing the action fetching code from NormandyApi.jsm
* Changing RecipeRunner to use the local implementations of clients
* Filing github issues on mozilla/normandy to remove (now) unused server-side action handling
Correction. "* Changing RecipeRunner to use the local implementations of clients" should read "local implementation of actions".
Priority: -- → P3
Blocks: 1436111
Summary: Implement actions internal to the client, instead of fetching from normandy-server → [Meta] Implement actions internal to the client, instead of fetching from normandy-server
Depends on: 1440777
Depends on: 1440778
Depends on: 1440779
Depends on: 1440780
Commit pushed to master at
Merge #1429

1429: Remove the control interace r=rehandalal a=mythmon

The control interface, aka the legacy admin panel, has been replaced by Delivery Console. This PR replaces it with a page that directs people to Delivery Console, removes all the code, and removes most of the build infrastructure that was used for it.

Remaining JS is the actions used by Normandy Client, which must be hosted by the server, until [bug 1436129]( is finished, and we have decided to officially unsupport any clients that don't have that change.

Fixes #1420.

Co-authored-by: Mike Cooper <>
No longer blocks: 1436111
Keywords: meta
Blocks: 1513646

All dependent bugs are resolved.

Closed: 2 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.