From bc6b6bbc26322c1366baf87f631ffc76820eff85 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Sun, 18 Mar 2018 16:01:22 +0100 Subject: [PATCH] Brain dumping the current plan for auto-updates --- Auto-update-internals.md | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 Auto-update-internals.md diff --git a/Auto-update-internals.md b/Auto-update-internals.md new file mode 100644 index 0000000..05d5877 --- /dev/null +++ b/Auto-update-internals.md @@ -0,0 +1,110 @@ +**Warning**: this feature has not been completely implemented in Dolphin yet. + +# Auto-update internals + +Dolphin will soon support an auto-update mechanism. We target Windows first, MacOS will come next. For Linux and Android we'll continue relying on platform mechanisms (package manager, Play Store), but hopefully following the same update tracks we'll be providing through auto-update. + +This wiki page documents how the auto-update system works. + +## Update tracks + +We will originally support 3 update tracks that users can choose from: + +* **Stable**: same frequency as our current stable releases. +* **Beta**: monthly updates synced with progress report. +* **Dev**: updates on every single change pushed to `dolphin-emu.org`. + +## Update check protocol + +To check for updates, Dolphin can hit the following API endpoint on `dolphin-emu.org`: + + GET /update/check/v0// + +* `` is the update track the user wants to follow (see next section). +* `` is the SHA1 hash of the current Dolphin version. + +This returns a JSON object with the following parameters: + + {"status": "up-to-date"} + + # OR + + { + "status": "outdated", + "content-store": "https://update.dolphin-emu.org/content/", # Content store base URL + "new": { + "hash": "aabbccdd...", # Version SHA1 + "name": "5.0-xxxx", # Readable version name + "manifest": "https://update.dolphin-emu.org/manifest/...", # Manifest URL + }, + "old": { + "hash": "00112233...", # Version SHA1 + "name": "5.0-yyyy", # Readable version name + "manifest": "https://update.dolphin-emu.org/manifest/...", # Manifest URL + }, + "changelog": [ + # One entry per version that is between old (non incl) and new (incl). + { + "shortrev": "5.0-xxxx", + "short_descr": "one line description of the change", + "author": "delroth", + "author_url": "https://github.com/delroth", + + # For changes that were issued from a pull request: + "pr_id": 4242, + "pr_url": "https://github.com/dolphin-emu/dolphin/pull/4242", + + # For changes on a manually curated update track: + "changelog_html": "Arbitrary HTML that describes the version.", + }, + ], + } + +## Update manifest + +The update manifest is a gzip compressed file which describes for each Dolphin version what files it contains. The format is as simple as it gets: + +* One file per line. Filename then `'\t'` then hex-encoded hash of the contents of the file. +* The hash algorithm we use is SHA256 truncated to 128 bits (`SHA256-128`). +* An empty line ends the list of files. +* The list of files is followed by a base64-encoded ed25519 signature of the list of files. + +Basically: + + Dir/File1 00112233445566778899aabbccddeeff + Dir/File2 00112233445566778899aabbccddeeff + + BASE64-SIGNATURE-HERE + +The public key of our build infrastructure is the following: `2ab3d1dc6ef507f6a06c7c54df54f44280a6288b6d7014b54c3495204dd4d35d`. + +Manifests are stored in the *manifest store*, publicly mapped to `https://update.dolphin-emu.org/manifest/`. The manifest of a version with SHA1 hash "aabbccddeeff...00112233" is located at `/manifest/aa/bb/ccddeeff...00112233.manifest`. Note however that you should always be using the manifest URLs from the update check response. + +## Content store + +All files that are present in a Dolphin release can be fetched using their SHA256-128 hash from our content store, mapped at `https://update.dolphin-emu.org/content/`. Note that the URL of the content store is returned in the update check response -- use that one instead of hardcoding. + +The gzip'd contents of a file with hash `00112233445566778899aabbccddeeff` can be found at `/content/00/11/2233445566778899aabbccddeeff`. You can verify that the contents do match the hash, for example: + + $ curl -s https://update.dolphin-emu.org/content/86/80/ed3a0deaed20812389f1a97bfd70 | gzip -cd | sha256sum | head -c -32 + 8680ed3a0deaed20812389f1a97bfd70 + +## Running the updater + +The Dolphin updater is `Updater.exe`, a separate binary from `Dolphin.exe`. It is designed to be able to run without depending on anything within the Dolphin install directory. + +When triggering an update, `Dolphin.exe` copies `Updater.exe` to a temporary location, and runs it with the following information provided through command line arguments: + +* URL of the current version and target version manifest (from the update check response). +* URL of the content store (from the update check response). +* Directory of the Dolphin installation to update. + +The updater is in charge of fetching the two manifests, diff-ing their contents, and generating: + +* A list of hashes to download from the content store. +* A list of files to update within the install directory. +* A list of files to delete from the install directory. + +Since these lists are fully generated from the manifest, before replacing or deleting any file, the updater can first check whether these files have been manually modified by the user. If that is the case, the modified contents are backed up to a `.bak` file before replacing / deleting. Only files present in the manifest are touched -- anything else that a user might have added manually to their directory is not touched (`portable.txt`, `User/`, ...). + +Downloaded contents are cached in a `TempUpdate` directory within the Dolphin install directory while the update process is going on. The updater is responsible for cleaning what it downloaded after execution, and remove the `TempUpdate` directory if it is empty. \ No newline at end of file