UpdateGeneration: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(Fix the link)
 
(7 intermediate revisions by 2 users not shown)
Line 5: Line 5:
== Current processes ==
== Current processes ==


Currently we use two different sets of processes and tools to generate updates for nightly updates and releases.  
Currently we use two different sets of processes and tools to generate updates for nightly updates and releases.


=== Nightly updates ===
=== Nightly updates during code development ===


We make updates available for official nightly builds for all current code branches. This helps ensure that our nightly testers are always running the most recent code with the least possible effort. These updates are offered on the 'nightly' update channel.
We make updates available for official nightly builds for all current code branches. This helps ensure that our nightly testers are always running the most recent code with the least possible effort. These updates are offered on the 'nightly' update channels, or derivates like 'nightly-ux', and for 'aurora'.


Both complete and partial updates are offered. If the user is running the most recent previous nightly build, the partial update is served. Otherwise, the complete update is always served. This greatly simplifies/expedites the update generation matrix.  
Both complete and partial updates are offered. If the user is running the most recent previous nightly build, the partial update is served. Otherwise, the complete update is always served. This greatly simplifies/expedites the update generation matrix.  


Steps for nightly update generation (3.5 branch and earlier):
Steps for nightly update generation:
* nightly builders generate complete MAR using Makefile
* nightly builder generate complete MAR using [https://searchfox.org/mozilla-central/source/tools/update-packaging Makefile]
* upload complete MAR to staging along with build
* nightly builder downloads the previous complete MAR from the latest dir on the staging server ([http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-mozilla-central/ eg])
* upload complete snippet to AUS2 server
* prometheus-vm runs cron script every 5 minutes (patch-packager-cron.sh) that calls patch-packager.pl. In the simplest terms, this script does the following:
*# Read in all of the available builds.
*# Compute all of the patches we could offer.
*# Read in all of the offered patches.
*# Compute which patches we aren't offering which we could.
*# Create all of the patches we could offer.
*# Upload them.
 
As of Firefox 3.6, we've stopped funneling all partial updates through prometheus-vm in favor of generating the partial updates directly on the builders. This gives us much quicker turnaround on update generation.
 
Steps for nightly update generation (3.6 branch, project branches, and later):
* nightly builder generate complete MAR using Makefile
* nightly builder downloads the previous complete MAR from the latest dir on the staging server
* nightly builder generates partial MAR containing the differences between the two complete MARS using Makefile
* nightly builder generates partial MAR containing the differences between the two complete MARS using Makefile
* nightly builder generates snippets for both the complete and partial updates
* nightly builder generates snippets for both the complete and partial updates
* nightly builder uploads snippets directly to the AUS2 server
* nightly builder uploads snippets directly to the AUS2 server


=== What the Makefiles do, or How to make your own updates ===
For more information about how the update MAR files are actually created, please see the section below entitled [[#What_the_Makefiles_do.2C_or_How_to_make_your_own_updates|How to make your own updates]].
 
=== Updates for end users ===
 
We create both partial and complete updates for the 'release' and 'beta' channel too.
 
Legitimate partial updates, i.e. binary diffs, are generated for migrating users from the previous security release to the new security release, e.g. 13.0->13.0.1. Complete mars are served to those users on older security releases, e.g. 12.0.
 
Steps for end-user update generation:
* similar to the nightly case, the build slave generates both a complete and a partial update
* snippets are generated using the patcher2 tool: http://mxr.mozilla.org/mozilla/source/tools/patcher/
* patcher generates both production ('release'/'beta') and testing ('releasetest'/'betatest') snippets, for QA to verify
 
=== Updates between major branches (aka major update) ===
Prior to Firefox 4.0, there were long lived branches that produced 3.5.x and 3.6.x releases. An update that converted users from 3.5.x to 3.6.x, or from 3.6.x to the latest release was known as a major update. They were characterised by displaying a dialog offering the user the new branch (ie new features) and asking them to accept the update. In the post-4.0 world these are not used as everyone gets a background update to the latest release, modulo OS compatibility. The only exceptions have been attempts to get people on older releases to update (eg Fx10 is current, offer to 6.0 and older).
 
== What the Makefiles do, or How to make your own updates ==
The build system generates update MAR files using the Makefile and associated scripts in the [http://hg.mozilla.org/mozilla-central/file/default/tools/update-packaging tools/update-packaging] source directory. The Makefile isn't strictly necessary though. It simply formats the calls to the other scripts based on values stored in environment variables, making it easier to automate update generation.
The build system generates update MAR files using the Makefile and associated scripts in the [http://hg.mozilla.org/mozilla-central/file/default/tools/update-packaging tools/update-packaging] source directory. The Makefile isn't strictly necessary though. It simply formats the calls to the other scripts based on values stored in environment variables, making it easier to automate update generation.


==== Creating a complete MAR ====
The scripts rely on some tools that normally get built as part of a nightly Firefox build, namely [http://hg.mozilla.org/mozilla-central/file/default/modules/libmar/tool mar] and [http://hg.mozilla.org/mozilla-central/file/default/other-licenses/bsdiff mbsdiff]. You can either builds your own set of tools from the mozilla source, or use a pre-packaged version of the tools for your platform.
This script used to generate a complete MAR file is [http://hg.mozilla.org/mozilla-central/file/default/tools/update-packaging/make_full_update.sh make_full_update.sh].  
 
These pre-packaged tools were taken from mozilla-central nightly builds on May 17, 2010:
* [http://ftp.mozilla.org/pub/mozilla.org/xulrunner/mar-generation-tools/mar-generation-tools-linux.zip mar-generation-tools-linux.zip]
* [http://ftp.mozilla.org/pub/mozilla.org/xulrunner/mar-generation-tools/mar-generation-tools-macosx.zip mar-generation-tools-macosx.zip]
* [http://ftp.mozilla.org/pub/mozilla.org/xulrunner/mar-generation-tools/mar-generation-tools-win32.zip mar-generation-tools-win32.zip]
XXX: These need updating for the maintenance service changes
 
=== Creating a complete MAR ===
This script used to generate a complete MAR file is [http://hg.mozilla.org/mozilla-central/file/default/tools/update-packaging/make_full_update.sh make_full_update.sh].


==== Creating a partial MAR ====
Here's a example of how you might use the complete update script:
 
BZIP2=/usr/bin/bzip2 \
MAR=~/bin/mar \
/tools/update-packaging/make_full_update.sh \
dist/update/firefox-3.7a5pre.en-US.linux-i686.complete.mar \
dist/firefox
 
* You need to provide the path to your MAR and BZIP2 executables as environment variables.
* The <code>make_full_update.sh</code> will then look in dist/firefox and generate a manifest of the files in that directory.
* That manifest will then be added to the output file specified, in this case dist/update/firefox-3.7a5pre.en-US.linux-i686.complete.mar, along with all the files themselves.
 
=== Creating a partial MAR ===
This script used to generate a partial MAR file is [http://hg.mozilla.org/mozilla-central/file/default/tools/update-packaging/make_incremental_update.sh make_incremental_update.sh].
This script used to generate a partial MAR file is [http://hg.mozilla.org/mozilla-central/file/default/tools/update-packaging/make_incremental_update.sh make_incremental_update.sh].


=== Updates for security releases ===
You'll need two complete MAR files in order to generate a partial MAR file that contains the delta between the two. The delta is computed using the binary patch generator, mbsdiff.


We create both partial and complete updates for security releases (aka as 'dot' releases, e.g. 3.5.x). These updates are only ever served to users on the same product branch.  
Once you have your two complete MAR files, you can unpack them each into their own directory by using the [http://hg.mozilla.org/mozilla-central/file/default/tools/update-packaging/unwrap_full_update.sh unwrap_full_update.sh] script as follows:


Legitimate partial updates, i.e. binary diffs, are generated for migrating users from the previous security release to the new security release, e.g. 3.5.1->3.5.2. Complete mars are served to those users on older security releases, e.g. 3.5->3.5.2. Because the updater checks for partial updates before complete updates, the update system serves the complete update for a security release as a partial update to all users on previous security releases. This avoids presenting the user with a failed check for a partial update that, while harmless, might be confusing.
# Given two MAR files, current.complete.mar and previous.complete.mar
export BZIP2=/usr/bin/bzip2
export MAR=~/bin/mar
mkdir current
pushd current
../tools/update-packaging/unwrap_full_update.sh /path/to/current.complete.mar
popd
mkdir previous
pushd previous
../tools/update-packaging/unwrap_full_update.sh /path/to/previous.complete.mar
popd


Steps for security release update generation:
'''NOTE''': you *MAY* need to modify the source of the <code>make_incremental_update.sh</code> script before you attempt to generate a the partial MAR. Specifically, the script contains a variable, [http://hg.mozilla.org/mozilla-central/file/05c4d3361afc/tools/update-packaging/make_incremental_update.sh#l51 requested_forced_updates]. Mozilla uses this variable to which control files that we want to *always* update.  
* partial MARs and AUS configuration data are generated using the patcher2 tool: http://mxr.mozilla.org/mozilla/source/tools/patcher/
* a release engineer puts the appropriate URLs, version numbers, and build IDs into the patcher configuration file: http://mxr.mozilla.org/mozilla/source/tools/patcher-configs/
* patcher downloads the complete MARs, creates partial diffs (using mbsdiff), and generates partial MAR files as well as AUS configuration files ("snippet" files).  
* patcher generates both production ("release") and testing ("releasetest") snippets, release snippets point to bouncer while releasetest snippets point to stage.
* partial MAR files are copied to the candidates directory, and the releasetest snippets are loaded into AUS.


=== Updates between major branches (aka major update) ===
If you have files in your MARs that should always be updated via a partial update (due to checksum changes, timestamps, whatever), you can either change the value of the variable in the script or simply pass the filenames via the -f flag to the <code>make_incremental_update.sh</code> script.


=== Which machines do what  ===
Here's a example of how you might use the partial update script:


{| cellpadding="5" border="1"
BZIP2=/usr/bin/bzip2 \
|-
MAR=~/bin/mar \
| '''Machine Name'''
MBSDIFF=~/bin/mbsdiff \
| '''Function'''
tools/update-packaging/make_incremental_update.sh \
|-
firefox-3.7a5pre.en-US.linux-i686.partial.previous-current.mar \
| any build slave
./previous \
| build generation<br/>complete patch(MAR) generation<br/>partial patch(MAR) generation (3.6+)<br/>XML snippet generation (3.6+)
./current
|-
| prometheus-vm
| partial patch(MAR) generation (3.5)<br/>XML snippet generation (3.5)
|-
| aus2-staging.mozilla.com
| store/serve snippets
|}


= Staging environment for nightly updates =
* As for the complete MAR file, you need to provide the path to your MAR and BZIP2 executables as environment variables, but also must provide the path to MBSDIFF.
* The <code>make_incremental_update.sh</code> will then compare the contents of the previous/ and current/ directories and generate a manifest and a binary diff of the files in those directory.
* That manifest will then be added to the output file specified, in this case firefox-3.7a5pre.en-US.linux-i686.partial.previous-current.mar, along with the binary diff of the changed files.


The staging environment for nightly updates consists of two machines:
=== Delivering updates via snippets ===
* staging-nightly-updates: this machine mirrors prometheus-vm in production, running the patch-packager scripts to generate partial mars based on update snippets published to...
The actual delivery of updates is beyond the scope of this page on update generation, but I'd feel remiss if I didn't at least mention in passing how it's done.
* staging-stage: used like stage.m.o in production to house builds and mars, but also holds the aus2 snippets used in update generation and publishing


== Common problems and resolutions with updates in the staging environment ==
After the complete and partial MAR files are generated and uploaded to the ftp server every night, we create a simple text file containing information about those MAR files. We call these files "snippets" and they have the following format:


=== Downloaded MAR file doesn't match the hash in the snippet ===
* Complete:
version=1
type=complete
url=http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2010/05/2010-05-21-03-mozilla-central/firefox-3.7a5pre.en-US.linux-i686.complete.mar
hashFunction=sha512
hashValue=f2d06098cca2ef9aa488c088ea709135eff875fbe5102e3a565d5d5af26daf88b79559db73295fb1066bb5ed8f4aa0353d795f2c561f7b8d05cdabacac57a94b
size=11216730
build=20100521030030
appv=3.7a5pre
extv=3.7a5pre


This can happen when two successful "nightly" builds start in the same hour (this shouldn't ever happen in production FWIW). The result is two different snippet files for two different mars, but only one mar in the corresponding build dir on staging-stage (these dirnames are only accurate down to the hour).
* Partial:
version=1
type=partial
url=http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2010/05/2010-05-21-03-mozilla-central/firefox-3.7a5pre.en-US.linux-i686.partial.20100520055328-20100521030030.mar
hashFunction=sha512
hashValue=2b707239c8219d2f97d1e6eba4f2cf90201e0b40ec18cd87cc3652b7779b8df031263962d52d90ec00cb3f0abbd98f310ae2636920a438444886f8a3da83bd13
size=460534
build=20100521030030
appv=3.7a5pre
extv=3.7a5pre


Removing the orphaned snippet should fix things up.
We then upload these snippets to the Mozilla [[AUS|AUS2]] server. The AUS2 server has internal logic to determine the most recent complete and partial updates available for a given product/branch/version, so that when the client updater requests an update from the server, it's able to redirect to the correct MAR file.

Latest revision as of 09:24, 13 January 2024

Update generation

One of the key features of Firefox is the update system that allows Mozilla to push out bug fixes and new features to users automatically.

Current processes

Currently we use two different sets of processes and tools to generate updates for nightly updates and releases.

Nightly updates during code development

We make updates available for official nightly builds for all current code branches. This helps ensure that our nightly testers are always running the most recent code with the least possible effort. These updates are offered on the 'nightly' update channels, or derivates like 'nightly-ux', and for 'aurora'.

Both complete and partial updates are offered. If the user is running the most recent previous nightly build, the partial update is served. Otherwise, the complete update is always served. This greatly simplifies/expedites the update generation matrix.

Steps for nightly update generation:

  • nightly builder generate complete MAR using Makefile
  • nightly builder downloads the previous complete MAR from the latest dir on the staging server (eg)
  • nightly builder generates partial MAR containing the differences between the two complete MARS using Makefile
  • nightly builder generates snippets for both the complete and partial updates
  • nightly builder uploads snippets directly to the AUS2 server

For more information about how the update MAR files are actually created, please see the section below entitled How to make your own updates.

Updates for end users

We create both partial and complete updates for the 'release' and 'beta' channel too.

Legitimate partial updates, i.e. binary diffs, are generated for migrating users from the previous security release to the new security release, e.g. 13.0->13.0.1. Complete mars are served to those users on older security releases, e.g. 12.0.

Steps for end-user update generation:

  • similar to the nightly case, the build slave generates both a complete and a partial update
  • snippets are generated using the patcher2 tool: http://mxr.mozilla.org/mozilla/source/tools/patcher/
  • patcher generates both production ('release'/'beta') and testing ('releasetest'/'betatest') snippets, for QA to verify

Updates between major branches (aka major update)

Prior to Firefox 4.0, there were long lived branches that produced 3.5.x and 3.6.x releases. An update that converted users from 3.5.x to 3.6.x, or from 3.6.x to the latest release was known as a major update. They were characterised by displaying a dialog offering the user the new branch (ie new features) and asking them to accept the update. In the post-4.0 world these are not used as everyone gets a background update to the latest release, modulo OS compatibility. The only exceptions have been attempts to get people on older releases to update (eg Fx10 is current, offer to 6.0 and older).

What the Makefiles do, or How to make your own updates

The build system generates update MAR files using the Makefile and associated scripts in the tools/update-packaging source directory. The Makefile isn't strictly necessary though. It simply formats the calls to the other scripts based on values stored in environment variables, making it easier to automate update generation.

The scripts rely on some tools that normally get built as part of a nightly Firefox build, namely mar and mbsdiff. You can either builds your own set of tools from the mozilla source, or use a pre-packaged version of the tools for your platform.

These pre-packaged tools were taken from mozilla-central nightly builds on May 17, 2010:

XXX: These need updating for the maintenance service changes

Creating a complete MAR

This script used to generate a complete MAR file is make_full_update.sh.

Here's a example of how you might use the complete update script:

BZIP2=/usr/bin/bzip2 \
MAR=~/bin/mar \
/tools/update-packaging/make_full_update.sh \
dist/update/firefox-3.7a5pre.en-US.linux-i686.complete.mar \
dist/firefox
  • You need to provide the path to your MAR and BZIP2 executables as environment variables.
  • The make_full_update.sh will then look in dist/firefox and generate a manifest of the files in that directory.
  • That manifest will then be added to the output file specified, in this case dist/update/firefox-3.7a5pre.en-US.linux-i686.complete.mar, along with all the files themselves.

Creating a partial MAR

This script used to generate a partial MAR file is make_incremental_update.sh.

You'll need two complete MAR files in order to generate a partial MAR file that contains the delta between the two. The delta is computed using the binary patch generator, mbsdiff.

Once you have your two complete MAR files, you can unpack them each into their own directory by using the unwrap_full_update.sh script as follows:

# Given two MAR files, current.complete.mar and previous.complete.mar
export BZIP2=/usr/bin/bzip2
export MAR=~/bin/mar
mkdir current
pushd current
../tools/update-packaging/unwrap_full_update.sh /path/to/current.complete.mar
popd
mkdir previous
pushd previous
../tools/update-packaging/unwrap_full_update.sh /path/to/previous.complete.mar
popd

NOTE: you *MAY* need to modify the source of the make_incremental_update.sh script before you attempt to generate a the partial MAR. Specifically, the script contains a variable, requested_forced_updates. Mozilla uses this variable to which control files that we want to *always* update.

If you have files in your MARs that should always be updated via a partial update (due to checksum changes, timestamps, whatever), you can either change the value of the variable in the script or simply pass the filenames via the -f flag to the make_incremental_update.sh script.

Here's a example of how you might use the partial update script:

BZIP2=/usr/bin/bzip2 \
MAR=~/bin/mar \
MBSDIFF=~/bin/mbsdiff \
tools/update-packaging/make_incremental_update.sh \
firefox-3.7a5pre.en-US.linux-i686.partial.previous-current.mar \
./previous \
./current
  • As for the complete MAR file, you need to provide the path to your MAR and BZIP2 executables as environment variables, but also must provide the path to MBSDIFF.
  • The make_incremental_update.sh will then compare the contents of the previous/ and current/ directories and generate a manifest and a binary diff of the files in those directory.
  • That manifest will then be added to the output file specified, in this case firefox-3.7a5pre.en-US.linux-i686.partial.previous-current.mar, along with the binary diff of the changed files.

Delivering updates via snippets

The actual delivery of updates is beyond the scope of this page on update generation, but I'd feel remiss if I didn't at least mention in passing how it's done.

After the complete and partial MAR files are generated and uploaded to the ftp server every night, we create a simple text file containing information about those MAR files. We call these files "snippets" and they have the following format:

  • Complete:
version=1
type=complete
url=http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2010/05/2010-05-21-03-mozilla-central/firefox-3.7a5pre.en-US.linux-i686.complete.mar
hashFunction=sha512
hashValue=f2d06098cca2ef9aa488c088ea709135eff875fbe5102e3a565d5d5af26daf88b79559db73295fb1066bb5ed8f4aa0353d795f2c561f7b8d05cdabacac57a94b
size=11216730
build=20100521030030
appv=3.7a5pre
extv=3.7a5pre
  • Partial:
version=1
type=partial
url=http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/2010/05/2010-05-21-03-mozilla-central/firefox-3.7a5pre.en-US.linux-i686.partial.20100520055328-20100521030030.mar
hashFunction=sha512
hashValue=2b707239c8219d2f97d1e6eba4f2cf90201e0b40ec18cd87cc3652b7779b8df031263962d52d90ec00cb3f0abbd98f310ae2636920a438444886f8a3da83bd13
size=460534
build=20100521030030
appv=3.7a5pre
extv=3.7a5pre

We then upload these snippets to the Mozilla AUS2 server. The AUS2 server has internal logic to determine the most recent complete and partial updates available for a given product/branch/version, so that when the client updater requests an update from the server, it's able to redirect to the correct MAR file.