From 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:47:29 +0200 Subject: Adding upstream version 115.8.0esr. Signed-off-by: Daniel Baumann --- toolkit/mozapps/update/docs/BackgroundUpdates.rst | 224 ++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 toolkit/mozapps/update/docs/BackgroundUpdates.rst (limited to 'toolkit/mozapps/update/docs/BackgroundUpdates.rst') diff --git a/toolkit/mozapps/update/docs/BackgroundUpdates.rst b/toolkit/mozapps/update/docs/BackgroundUpdates.rst new file mode 100644 index 0000000000..c692f4958a --- /dev/null +++ b/toolkit/mozapps/update/docs/BackgroundUpdates.rst @@ -0,0 +1,224 @@ +================== +Background Updates +================== + +The purpose of the background update system is to perform application updates +during times when Firefox is not running. It was originally implemented in `bug +1689520 `__. + +The system has three main tasks it needs to handle: + +1. :ref:`Determining whether background updates are possible ` + +2. :ref:`Scheduling background tasks ` + +3. :ref:`Checking for updates ` + +Architecturally, the background task is an instance of Firefox running in a +special background mode, not a separate tool. This allows it to leverage +existing functionality in Firefox, including the existing update code, but also +keep acceptable performance characteristics for a background task by controlling +and limiting the parts of Firefox that are loaded. + +Everything in this document applies only to Microsoft Windows systems. In the +future, we would like to extend background update support to macOS (see `bug +1653435 `__), however +support for Linux and other Unix variants is not planned due to the variation in +OS-level scheduling affordances across distributions/configurations. + +Lifecycle +========= + +When background updates are possible, the background update task will be invoked +every 7 hours (by default). The first invocation initiates an update download +which proceeds after the task exits using Windows BITS. The second invocation +prepares and stages the update. The third invocation installs the update as it +starts up, and then checks for a newer update, possibly initiating another +update download. The cycle then continues. If the user launches Firefox at any +point in this process, it will take over. If the background update task is +invoked while Firefox proper is running, the task exits without doing any work. +In the future, the second invocation will stage and then restart to finish +installing the update, rather than waiting for the third invocation (see `bug +1704855 `__). + +.. _background-updates-determining: + +Determining whether background updates are possible +=================================================== + +Configuration +------------- + +Updating Firefox, by definition, is an operation that applies to a Firefox +installation. However, Firefox configuration is generally done via preference +values and other files which are stored in a Firefox profile, and in general +profiles do not correspond 1:1 with installations. This raises the question of +how the configuration for something like the background updater should be +managed. We deal with this question in two different ways. + +There are two main preferences specifically relevant to updates. Those +are ``app.update.auto``, which controls whether updates should be +downloaded automatically at all, even if Firefox is running, and +``app.update.background.enabled``, to specifically control whether to +use the background update system. We store these preferences in the +update root directory, which is located in a per-installation location +outside of any profile. Any profile loaded in that installation can +observe and control these settings. + +But there are some other pieces of state which absolutely must come from a +profile, such as the telemetry client ID and logging level settings (see +`BackgroundTasksUtils.jsm `__). + +This means that, in addition to our per-installation prefs, we also need +to be able to identify and load a profile. To do that, we leverage `the profile +service `__ +to determine what the default profile for the installation would be if we were +running a normal browser session, and the background updater always uses it. + +Criteria +-------- + +The default profile must satisfy several conditions in order for background +updates to be scheduled. None of these confounding factors are present in fully +default configurations, but some are relatively common. See +`BackgroundUpdate.REASON `__ +for all the details. + +In order for the background task to be scheduled: + +- The per-installation ``app.update.background.enabled`` pref must be + true + +- The per-installation ``app.update.auto`` pref must be true (the + default) + +- The installation must have been created by an installer executable and not by + manually extracting an archive file + +- The current OS user must be capable of updating the installation based on its + file system permissions, either by having permission to write to application + files directly or by using the Mozilla Maintenance Service (which also + requires that it be installed and enabled, as it is by default) + +- BITS must be enabled via ``app.update.BITS.enabled`` (the default) + +- Firefox proxy server settings must not be configured (the default) + +- ``app.update.langpack.enabled`` must be false, or otherwise there must be no + langpacks installed. Background tasks cannot update addons such as langpacks, + because they are installed into a profile, and langpacks that are not + precisely matched with the version of Firefox that is installed can cause + YSOD failures (see `bug 1647443 `__), + so background updating in the presence of langpacks is too risky. + +If any per-installation prefs are changed while the default profile is not +running, the background update task will witness the changed prefs during its +next scheduled run, and exit if appropriate. The background task will not be +unscheduled at that point; that is delayed until a browser session is run with +the default profile (it should be possible for the background update task to +unschedule itself, but currently we prefer the simplicity of handling all +scheduling tasks from a single location). + +In the extremely unusual case when prefs belonging to the default profile are +modified outside of Firefox (with a text editor, say), then the +background task will generally pick up those changes with no action needed, +because it will fish the changed settings directly from the profile. + +.. _background-updates-scheduling: + +Scheduling background tasks +=========================== + +We use OS-level scheduling mechanisms to schedule the command ``firefox +--backgroundtask backgroundupdate`` to run on a particular cadence. This cadence +is controlled by the ``app.update.background.interval`` preference, which +defaults to 7 hours. + +On Windows, we use the `Task Scheduler +API `__; +on macOS this will use +`launchd `__. +For platform-specific scheduling details, see the +`TaskScheduler.jsm `__ +module. + +These background tasks are scheduled per OS user and run with that user’s +permissions. No additional privileges are requested or needed, regardless of the +user account's status, because we have already verified that either the user has +all the permissions they need or that the Maintenance Service can be used. + +Scheduling is done from within Firefox (or a background task) itself. To +reduce shared state, only the *default* Firefox profile will interact +with the OS-level task scheduling mechanism. + +.. _background-updates-checking: + +Checking for updates +==================== + +After verifying all the preconditions and exiting immediately if any do not +hold, the ``backgroundupdate`` task then verifies that it is the only Firefox +instance running (as determined by a multi-instance lock, see `bug +1553982 `__), since +otherwise it would be unsafe to continue performing any update work. + +The task then fishes configuration settings from the default profile, namely: + +- A subset of update specific preferences, such as ``app.update.log`` + +- Data reporting preferences, to ensure the task respects the user’s choices + +- The (legacy) Telemetry client ID, so that background update Telemetry + can be correlated with other Firefox Telemetry + +The background task creates a distinct profile for itself to load, because a +profile must be present in order for most of the Firefox code that it relies on +to function. This distinct profile is non-ephemeral, i.e., persistent, but not +visible to users: see `bug 1775132 +`__ + +After setting up this profile and reading all the configuration we need +into it, the regular +`UpdateService.jsm `__ +check process is initiated. To the greatest extent possible, this process is +identical to what happens during any regular browsing session. + +Specific topics +=============== + +User interface +-------------- + +The background update task must not produce any user-visible interface. If it +did, whatever appeared would be \*disembodied\*, unconnected to any usage of +Firefox itself and appearing to a user as a weird, scary popup that came out of +nowhere. To this end, we disable all UI within the updater when invoking +from a background task. See `bug +1696276 `__. + +This point also means that we cannot prompt for user elevation (on Windows this +would mean a UAC prompt) from within the task, so we have to make very sure that +we will be able to perform an update without needing to elevate. By default on +Windows we are able to do this because of the presence of the Maintenance +Service, but it may be disabled or not installed, so we still have to check. + +Staging +------- + +The background update task will follow the update staging setting in the user’s +default profile. The default setting is to enable staging, so most users will +have it. In the future, background update tasks will recognize when an update +has been staged and try to restart to finalize the staged update (see `bug +1704855 `__). Background +tasks cannot finalize a staged update in all cases however; for one example, see +`bug 1695797 `__, where we +ensure that background tasks do not finalize a staged update while other +instances of the application are running. + +Staging is enabled by default because it provides a marked improvement in +startup time for a browsing session. Without staging, browser startup following +retrieving an update would be blocked on extracting the update archive and +patching each individual application file. Staging does all of that in advance, +so that all that needs to be done to complete an update (and therefore all that +needs to be done during the startup path), is to move the already patched (that +is, staged) files into place, a much faster and less resource intensive job. -- cgit v1.2.3