diff --git a/README.md b/README.md index de94de6d..c36c9870 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,9 @@ `emulebb-rust` is the active automation-first Rust eD2K/Kad client in the eMuleBB organization. It owns the Rust-forward `/api/v1` contract, runs as a headless daemon, and serves an embedded browser operations console from -packaged static assets. It keeps the complete profile in one SQLite database. +packaged static assets. Durable runtime metadata lives in one SQLite database; +bootstrap configuration, retained logs, and protocol bootstrap files remain +separate profile artifacts. This is a Rust-native successor to the Windows eMuleBB MFC fork, not a line-by-line port or an MFC REST-contract mirror. Stock/community eMule owns @@ -42,19 +44,23 @@ oriented async I/O is the baseline, not a compatibility toggle. API, configuration, and schema compatibility remain explicitly unstable through Client, Indexer, and Arr and freeze together only after the Arr gate. An incompatible schema fails startup and requires an entirely fresh profile; -the product does not migrate, reset, repair, or partially rebuild it. +the product does not migrate, reset, repair, or partially rebuild it. The +legacy eMule importer below creates a current Rust profile and is not a migration +path between incompatible Rust metadata schemas. Active product docs, backlog, design notes, release scope, and the Rust OpenAPI -contract live in -`EMULEBB_WORKSPACE_ROOT\repos\emulebb-tooling\docs\products\emulebb-rust`. -The repo-local `docs` directory is only a pointer. +contract live in the public +[emulebb-tooling product docs](https://github.com/emulebb/emulebb-tooling/tree/main/docs/products/emulebb-rust). +Maintainer workspaces materialize the same tree under +`EMULEBB_WORKSPACE_ROOT\repos\emulebb-tooling\docs\products\emulebb-rust`; the +repo-local `docs` directory is only a pointer. New contributors should start with [`CONTRIBUTING.md`](CONTRIBUTING.md) and the public [eMuleBB Roadmap](https://github.com/orgs/emulebb/projects/3). The beta is published; new work should be scoped through the normal issue and validation process rather than the former pre-release freeze. -## 0.1.0-beta.2 Shape +## Current Client Shape - `emulebb-daemon`: CLI, config, logging, and REST listener. - `emulebb-rest`: Rust-native `/api/v1` routes, envelopes, and API-key @@ -75,6 +81,12 @@ The former native Slint client has been removed. The supported product shape is the headless daemon plus its REST API and embedded SPA WebUI; release cleanup still rejects stale `emulebb-rust-ui` artifacts from older build directories. +Current `main` also includes searchable and paged shared-file operations with +per-file eD2K/Kad publication state, large-library watcher and hashing +improvements, and the one-shot legacy profile importer documented below. These +are development-channel behavior and appear in a nightly only after that exact +`main` revision passes and is published. + ## Rust Client Policy The Rust client supports Windows, Linux, and macOS on x64 and ARM64. Every @@ -91,8 +103,8 @@ not change the semantics of supported stock interactions. Rust source is split by subsystem and responsibility, not by a mechanical line limit. Substantial tests stay outside production modules; small white-box tests may remain beside private helpers when proximity improves understanding. The -authoritative rules live in -`EMULEBB_WORKSPACE_ROOT\repos\emulebb-tooling\docs\products\emulebb-rust\reference\CODE-QUALITY.md`. +authoritative rules live in the public +[Rust code-quality policy](https://github.com/emulebb/emulebb-tooling/blob/main/docs/products/emulebb-rust/reference/CODE-QUALITY.md). The policy checker reports maintainability signals as advisories while retaining hard failures for objective protocol, omission, binding, and release-safety violations. Normal CI also validates every GitHub Actions workflow with a pinned @@ -155,22 +167,6 @@ profile directory and bootstrap file with modes `0700` and `0600`. Existing Unix bootstrap files with group or other access are rejected with a `chmod 600` remediation message because the file contains the REST credential. -The one-shot profile importer is the explicit-profile bootstrap exception. It -creates a fresh target profile when needed, atomically merges a portable -manifest generated by `repos/emulebb-build-tests/scripts/export-emule-profile.py`, -and exits without starting networking: - -```powershell -$rust = Join-Path $env:EMULEBB_WORKSPACE_OUTPUT_ROOT "tools\emulebb-rust\bin\emulebb-rust.exe" -$profile = Join-Path $env:EMULEBB_WORKSPACE_OUTPUT_ROOT "profiles\imported-rust" -$manifest = Join-Path $env:EMULEBB_WORKSPACE_OUTPUT_ROOT "inputs\emule-profile-import.json" -& $rust --profile $profile import-emule-profile $manifest -``` - -Keep the target client stopped while importing. The manifest contains reusable -stock-compatible known-file hashes and shared roots, not identity, credits, -network bootstrap state, settings, or partial downloads. - The daemon serves plain HTTP. Keep direct listeners on loopback whenever possible. A non-loopback listener is intended for a container network or a trusted TLS reverse proxy and emits a startup warning; independently restrict @@ -183,7 +179,108 @@ running and `503` during graceful shutdown; it exposes no profile, peer, network, or credential data. The OCI image uses this loopback-only probe for its built-in healthcheck. -### Upload queue settings migration +## Import An Existing eMule Profile + +The one-shot importer can bootstrap a current Rust profile from a stopped stock +eMule or eMuleBB MFC profile without re-hashing unchanged shared files. It does +not modify the source profile. Back it up anyway, and keep both the legacy +client and the target Rust client stopped throughout export and apply. + +The importer landed after `0.1.0-beta.2`. Use a nightly whose generated release +notes include `RUST-FEAT-052`, or build current `main`; the formal Beta 2 +executable does not provide the `import-emule-profile` command. + +Import has two explicit stages: + +1. The public + [`emulebb-build-tests` exporter](https://github.com/emulebb/emulebb-build-tests/blob/main/scripts/export-emule-profile.py) + reads the legacy profile and writes a portable JSON manifest. +2. `emulebb-rust import-emule-profile` validates and merges that manifest in one + SQLite transaction, prints a JSON summary, and exits without starting + networking. + +The exporter requires Git and Python 3.10 or newer. Clone it separately from the +Rust release, install its small Python package, and copy the +[example TOML job](https://github.com/emulebb/emulebb-build-tests/blob/main/manifests/emule-profile-import.example.toml) +to an operator-owned location: + +```powershell +git clone https://github.com/emulebb/emulebb-build-tests.git +Push-Location .\emulebb-build-tests +python -m pip install -e . +$job = Join-Path $env:TEMP "emule-profile-import.toml" +Copy-Item .\manifests\emule-profile-import.example.toml $job +``` + +Edit the copied job. `source.profile` may name either the legacy profile root or +its `config` directory. `source.flavor = "auto"` detects stock eMule versus the +eMuleBB MFC monitored-root extensions. Relative paths are resolved from the TOML +file, so absolute paths are recommended for operator jobs: + +```toml +schema_version = 1 + +[source] +profile = 'C:\path\to\emule-profile' +flavor = "auto" + +[target] +platform = "windows" + +[output] +manifest = 'C:\path\to\emule-profile-import.json' +``` + +For Windows-to-Windows import, unmatched shared roots keep their existing paths. +For Linux, macOS, or Docker, set the target platform accordingly and map every +discovered Windows root to the absolute path visible to the target daemon. +Mappings use longest-prefix, path-boundary matching and may be repeated: + +```toml +[target] +platform = "linux" + +[[path_mappings]] +source = 'D:\Shared' +target = '/data/shared' +``` + +Validate first, then export the manifest: + +```powershell +python .\scripts\export-emule-profile.py check --config $job +python .\scripts\export-emule-profile.py export --config $job +Pop-Location +``` + +Apply the manifest with the Rust executable for the configured target platform. +The `--profile` argument is required. A missing target profile is created with a +generated WebUI API key; record the key printed by the command. An existing +target must already use the current Rust metadata schema. + +```powershell +$rust = 'C:\path\to\emulebb-rust.exe' +$profile = 'C:\path\to\new-rust-profile' +$manifest = 'C:\path\to\emule-profile-import.json' +& $rust --profile $profile import-emule-profile $manifest +& $rust --profile $profile +``` + +The exporter reads `known.met`, optional `known2.met`/`known2_64.met`, Incoming, +and explicit or monitored shared roots. It carries reusable ED2K and AICH +hashsets, upload priority, and all-time upload statistics. It intentionally does +not migrate client identity, credits, settings, server/Kad bootstrap state, or +partial downloads. + +Stock `known.met` records do not contain full source paths. On the first shared +scan, Rust reuses an imported hash only for one unique exact match by filename, +size, and modification time at one-second resolution. Changed files, ambiguous +duplicates, missing metadata, and unmatched files follow the normal hashing +path. Applying the same valid manifest again is safe and preserves current +native Rust metadata and shared roots; any validation or transaction failure +leaves no partial import. + +## Upload Queue Settings Migration The beta settings contract has one owner for each upload scheduling input. The following former `ed2k.uploadQueue` fields are no longer accepted; update saved @@ -244,10 +341,11 @@ schedule using the extended security query suite. ## Beta.2 artifacts -The public [release notes](https://github.com/emulebb/emulebb-tooling/blob/main/docs/products/emulebb-rust/RELEASE-0.1.0-beta.2-NOTES.md), -[changelog](https://github.com/emulebb/emulebb-tooling/blob/main/docs/products/emulebb-rust/RELEASE-0.1.0-beta.2-CHANGELOG.md), -and [release scope](https://github.com/emulebb/emulebb-tooling/blob/main/docs/products/emulebb-rust/RELEASE-SCOPE.md) -are the version-specific operator and compatibility references. +The published +[`0.1.0-beta.2` GitHub Release](https://github.com/emulebb/emulebb-rust/releases/tag/rust-v0.1.0-beta.2) +owns its release notes and assets. The canonical +[release scope](https://github.com/emulebb/emulebb-tooling/blob/main/docs/products/emulebb-rust/RELEASE-SCOPE.md) +records the current compatibility boundary. The manual [release workflow](.github/workflows/release.yml) retains candidate artifacts for Windows, Linux, and macOS on x64 and ARM64. Native ZIP, diff --git a/docs/README.md b/docs/README.md index 2d317c00..f73a4fac 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,7 +1,10 @@ # emulebb-rust Docs The canonical emulebb-rust product, backlog, design, release, history, and API -docs live in: +docs are public in the +[emulebb-tooling repository](https://github.com/emulebb/emulebb-tooling/tree/main/docs/products/emulebb-rust). + +Maintainer workspaces materialize the same docs at: `EMULEBB_WORKSPACE_ROOT\repos\emulebb-tooling\docs\products\emulebb-rust`