Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 127 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -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`

Expand Down
Loading