diff --git a/quest/m2/README.md b/quest/m2/README.md index 8b227e7be2..b558eb30c8 100644 --- a/quest/m2/README.md +++ b/quest/m2/README.md @@ -186,6 +186,8 @@ before format-specific metadata. Unrelated areas can proceed in parallel. - [#2907](/quest/m2/2907-bind-the-browser-through-moq-ffi-uniffi-instead-of-a.md) - Bind the browser through moq-ffi/UniFFI instead of a second hand-written wasm API - [#2850](/quest/m2/2850-js-net-give-reader-a-synchronous-decode-so-the-publisher.md) - js/net: decode messages synchronously from buffered bytes and delete the publisher read-ahead queue (dev) - [Cluster flags](/quest/m2/cluster-flags.md) - a discovery mechanism carries its own prerequisites, so an incomplete cluster config cannot be expressed +- [Install moq](/quest/m2/moq-installer.md) - one command installs or upgrades the released CLI on macOS and Linux +- [Install URL](/quest/m2/moq-install-url.md) - moq.dev serves the canonical installer at /install.sh - [`moq relay`](/quest/m2/moq-relay-subcommand.md) - the relay runs under a `moq` verb with its own flags and TOML, while `moq-relay` stays a minimal binary - [`moq` serves like a relay](/quest/m2/cli-serve.md) - a `moq --listen` session is authenticated, scoped, counted, and drained like a relay's; the relay is `moq` listening by default - [#3137](/quest/m2/3137-moqsrc-bound-the-pending-rendition-subscriptions-a.md) - moqsrc: bound the pending rendition subscriptions a catalog can open diff --git a/quest/m2/moq-install-url.md b/quest/m2/moq-install-url.md new file mode 100644 index 0000000000..a5416887fd --- /dev/null +++ b/quest/m2/moq-install-url.md @@ -0,0 +1,34 @@ +# [S] Publish the moq.dev install URL + +## Goal + +`curl -fsSL https://moq.dev/install.sh | bash` installs or upgrades `moq` +using the canonical installer from moq-dev/moq. The short URL works without +maintaining another copy of the install logic. + +## Plan + +- Implement the hosting change in **moq-dev/moq.dev**, which owns the root + website, not moq.pro. Track this cross-repository work here beside its + installer dependency; complete this quest only after the website change + and final documentation update have landed. +- Reuse the site's existing asset/Worker publishing path to expose the + canonical installer over HTTPS, preferably with a redirect to its published + source. If using a Worker redirect, include `/install.sh` in + `assets.run_worker_first` so a missing static asset cannot bypass the route. + Preserve non-success responses for unavailable scripts rather than serving + the site's HTML fallback. Keep redirect and cache behavior compatible with + updates to the canonical installer. +- Verify the route on `new.moq.dev` and test the complete redirected download. + Run the downloaded script in a temporary install directory and confirm + `moq --version`. Verify the public URL after an authorized production deploy; + this plan does not authorize a production deployment. +- Switch `doc/setup/install.md` in moq-dev/moq to the short URL once it is + working. Keep upgrade and version-selection examples aligned with the + canonical installer's interface. Add route coverage to the site's normal + checks for the shell response/redirect and error behavior. + +## Required + +- [Install moq](/quest/m2/moq-installer.md) - canonical installer, release + selection, upgrade behavior, and tests are published first diff --git a/quest/m2/moq-installer.md b/quest/m2/moq-installer.md new file mode 100644 index 0000000000..3656af187f --- /dev/null +++ b/quest/m2/moq-installer.md @@ -0,0 +1,84 @@ +# [M] One-command moq installation and upgrades + +## Goal + +A canonical Bash installer installs the released `moq` binary on supported +macOS and Linux machines without Rust or sudo. Running it again upgrades +the same installation; selecting a version supports +reproducible installs and deliberate downgrades. + +Install only `moq` from the `moq-cli` release. Token and relay functionality +belong to its subcommands, not separate installer choices. This work does +not implement those subcommands, automatic updates, a self-update command, +service setup, Windows support, or new release targets. + +## Plan + +- Default to the latest stable `moq-cli` release, with an explicit version + option. Resolve that product's tags, not the repository-wide latest + release: this repository publishes multiple independently versioned crates. + Refuse missing versions, malformed input, and incomplete releases clearly. +- Reuse the release archives and `SHA256SUMS`. Verify the selected archive + before extracting and installing its expected executable. Stage and check + the replacement before modifying the destination. Commit the executable and + ownership record as one recoverable transaction on the destination + filesystem: stage the new pair, retain the validated prior pair, and write a + durable journal before either rename. Record distinct phases after the + executable rename and after the ownership-record rename. On a handled + failure, roll back both files. After interruption, the next run must use the + journal to complete the new pair when both staged objects validate together. + If both renames completed, validate the installed pair and finish cleanup; + otherwise restore the prior pair, or remove every transaction file for an + initial install. Recovery must not misclassify a partial transaction as an + unmanaged installation. + Flush staged files, journal updates, renames, and their directory entries at + the required commit boundaries. Remove the journal and backups only after the + matching pair is durable. This is the atomic installation contract: recovery + exposes either the complete old pair or the complete new pair, never a mixed + pair. A failed initial install leaves no destination, while a failed upgrade + leaves the prior executable and ownership record usable. Clean up temporary + files after commit or rollback. +- Support the existing targets: macOS ARM64 and Linux x86_64/ARM64 with + glibc 2.34 or newer. Refuse unsupported operating systems, architectures, + and libc variants with actionable diagnostics. Intel macOS and musl/Alpine + require separate release work. +- Default to `~/.local/bin` with an explicit directory override. Do not invoke + sudo or edit shell profiles. Print the installed version and path, and + shell-appropriate PATH instructions when needed. Detect when another + `moq` on PATH would take precedence so success does not imply the wrong + binary will run. Do not follow an existing destination symlink into a + package manager's installation or overwrite a conflicting unmanaged file. + Keep a durable ownership record bound to the destination and installed + binary digest. Refuse replacement when the record is missing, malformed, + or mismatched, including a record copied from another destination. A valid + prior installation can be replaced; failed upgrades must preserve both its + binary and usable ownership record. +- Keep the canonical script and its tests in this repository. Publish a + usable HTTPS source for the dependent website quest; that quest exposes + `https://moq.dev/install.sh` without duplicating installer logic. +- Document first install, latest-version upgrade, explicit version selection, + directory override, PATH setup, and removal in `doc/setup/install.md`. + Use the working canonical URL until the website quest switches the example. + Package-manager installations continue to use their package manager for + upgrades. Describe only the subcommands the selected release actually ships. +- Wire installer tests into `just check` or `just test` and CI. Cover initial + install, repeat install, upgrade, explicit downgrade, product-specific latest + selection, unsupported hosts, corrupt/missing assets, destination conflicts, + and failure preserving an existing executable. Use controlled fixtures for + failure cases, including interruption before and after every journal, rename, + durability, and cleanup boundary. Explicitly cover the post-second-rename, + pre-cleanup state. Assert that each case completes the new pair or restores + the old pair, and that an initial-install failure leaves neither file. Add + native macOS/Linux smoke coverage for executable startup. + Exercise the canonical script with real release assets in a temporary + install directory and run the installed `moq --version`. The dependent + website quest owns verification of the final public URL. + +## Related + +- [Binary release workflow](/quest/m2/tooling/release-binary.md) - reuse its + artifacts without requiring workflow consolidation +- [`moq relay`](/quest/m2/moq-relay-subcommand.md) - relay functionality joins + the same executable independently of its installation method +- [Install URL](/quest/m2/moq-install-url.md) - exposes this installer through + the moq.dev website after it is published