v0.32.8
This commit is contained in:
1 parent
c41d1e00a2
commit
6987b3ce33
98 files changed
+146
-10827
No files matched your search
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Detect mixed source trees and preserve the known obsolete 0.0.1 auth module."""
|
||||
from __future__ import annotations
|
||||
import argparse
|
||||
import hashlib
|
||||
import re
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
LEGACY_AUTH = "4df9d473c9214365d91c83072f97aafab6ede4edcf4e1369b5c3679ded5cff85"
|
||||
|
||||
|
||||
def check(root: Path, repair_known: bool = False) -> list[str]:
|
||||
messages: list[str] = []
|
||||
|
||||
# 0.25.1 split-source migration: these monoliths are obsolete when the new
|
||||
# bounded module tree is present. Preserve any local edits instead of silently
|
||||
# deleting them when a source archive is extracted over an older checkout.
|
||||
obsolete_split_files = (
|
||||
"src/admin/web/app.js",
|
||||
"src/admin/web/vhosts.js",
|
||||
"src/web_server.rs",
|
||||
)
|
||||
split_markers = {
|
||||
"src/admin/web/app.js": "src/admin/web/app/core.js",
|
||||
"src/admin/web/vhosts.js": "src/admin/web/vhosts/core.js",
|
||||
"src/web_server.rs": "src/web_server/mod.rs",
|
||||
}
|
||||
for relative in obsolete_split_files:
|
||||
obsolete = root / relative
|
||||
marker = root / split_markers[relative]
|
||||
if not obsolete.exists() or not marker.is_file():
|
||||
continue
|
||||
if not repair_known:
|
||||
raise ValueError(
|
||||
f"Obsolete 0.25.0 source monolith {relative} remains beside the 0.25.1 split tree. "
|
||||
"Run ./dev.sh repair (or any normal ./dev.sh command) to preserve it under .upgrade-backup/."
|
||||
)
|
||||
backup_root = root / ".upgrade-backup" / "0.25.1-split"
|
||||
target = backup_root / relative
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
if target.exists():
|
||||
# Never overwrite a prior backup; if the bytes match, the current stale
|
||||
# copy can simply be removed. Otherwise force the operator to reconcile it.
|
||||
if target.read_bytes() != obsolete.read_bytes():
|
||||
raise ValueError(
|
||||
f"Backup target {target.relative_to(root)} already contains different data; "
|
||||
f"move {relative} outside the source tree manually before rebuilding."
|
||||
)
|
||||
obsolete.unlink()
|
||||
else:
|
||||
obsolete.rename(target)
|
||||
messages.append(
|
||||
f"Preserved obsolete {relative} as {target.relative_to(root)}"
|
||||
)
|
||||
|
||||
legacy = root / "src/auth.rs"
|
||||
if legacy.exists() and (root / "src/auth/mod.rs").is_file():
|
||||
if legacy.is_symlink() or hashlib.sha256(legacy.read_bytes()).hexdigest() != LEGACY_AUTH:
|
||||
raise ValueError("Both src/auth.rs and src/auth/mod.rs exist. The single-file module is not the known 0.0.1 file. Preserve your edits and move it outside src before rebuilding. See docs/MIGRATION.md.")
|
||||
if not repair_known:
|
||||
raise ValueError("Known obsolete src/auth.rs from 0.0.1 found. Run ./dev.sh repair or start ./dev.sh to preserve it in .upgrade-backup/legacy-auth/.")
|
||||
directory = root / ".upgrade-backup/legacy-auth"
|
||||
directory.mkdir(parents=True, exist_ok=True)
|
||||
target = directory / "auth.rs.0.0.1"
|
||||
if target.exists():
|
||||
if hashlib.sha256(target.read_bytes()).hexdigest() != LEGACY_AUTH:
|
||||
raise ValueError("Legacy backup path contains a different file; refusing to overwrite it.")
|
||||
legacy.unlink() # Byte-identical content was already preserved.
|
||||
else:
|
||||
legacy.rename(target)
|
||||
messages.append("Preserved obsolete src/auth.rs as .upgrade-backup/legacy-auth/auth.rs.0.0.1")
|
||||
for module in (root / "src").rglob("mod.rs"):
|
||||
flat = module.parent.with_suffix(".rs")
|
||||
if flat.is_file():
|
||||
raise ValueError(f"Conflicting Rust modules: {flat.relative_to(root)} and {module.relative_to(root)}")
|
||||
for path in ["src/auth/mod.rs", "src/auth/store.rs", "src/backup/snapshot.rs", "src/upstream.rs", "src/tls.rs", "src/config/internal_routing.rs", "src/proxy/websocket.rs", "src/proxy/error_fallback.rs", "src/cache/mod.rs", "src/cache/model.rs", "src/cache/lifecycle.rs", "src/cache/cold.rs", "src/cache/dashboard.rs", "src/cache/tickets.rs", "src/cache/lookup.rs", "src/cache/policy.rs", "src/cache/fill.rs", "src/cache/tests.rs", "src/settings.rs", "src/compression.rs", "src/diagnostics.rs", "src/traffic.rs", "src/system_stats/mod.rs", "src/system_stats/linux.rs", "src/vhost.rs", "src/vhost/error_fallback.rs", "src/web_server/mod.rs", "src/web_server/config.rs", "src/web_server/filesystem.rs", "src/web_server/security.rs", "src/web_server/response.rs", "src/web_server/request.rs", "src/web_server/routing.rs", "src/web_server/fastcgi.rs", "src/web_server/htaccess.rs", "src/web_server/serve.rs", "src/web_server/tests.rs", "src/balance.rs", "src/security.rs", "src/admin/web/vhosts/core.js", "src/admin/web/vhosts/rates.js", "src/admin/web/vhosts/health.js", "src/admin/web/vhosts/editor.js", "src/admin/web/vhosts/render.js", "src/admin/web/web-server.js", "src/admin/web/streams.js", "src/admin/web/host404.js", "src/admin/web/app/core.js", "src/admin/web/app/session-resume.js", "src/admin/web/app/preferences.js", "src/admin/web/app/config-history.js", "src/admin/web/app/runtime.js", "src/admin/web/app/settings.js", "src/admin/web/management.js", "src/admin/web/drafts.js", "src/pages.rs", "tools/dev/mock_server.py", "tools/dev/mock_auth.py", "src/forwarding.rs", "src/tinyauth.rs", "src/http3.rs", "src/stream.rs", "src/admin/web/integrations.js", "src/admin/web/traffic-panel.js", "src/prometheus.rs", "src/admin/web/settings.js", "src/admin/web/docker.js", "src/docker.rs", "docker-agent/main.go", "docker-agent/model.go", "docker-agent/docker.go", "docker-agent/network.go", "docker-agent/certificate.go", "docker-agent/server.go", "docker-agent/main_test.go", "docker-agent/rustproxy-docker-agent.service", "docker-agent/install.sh", "docs/DOCKER_DISCOVERY.md", "docs/WEB_SERVER.md", "docs/PHP_FPM.md", "docs/README.md", "docs/TODO.md", "docs/CHANGELOG_TECHNICAL_ARCHIVE.md", "docs/ROADMAP_HISTORY.md", "scripts/runtime/acme_provider.py", "src/basic_auth.rs", "scripts/deploy/deploy.py", "scripts/deploy/deploy_core.py", "scripts/deploy/deploy_runtime.py", "scripts/migration/migrate_npm.py", "scripts/migration/migrate_npm_core.py", "scripts/migration/migrate_npm_api.py", "docs/NPM_MIGRATION.md", "docs/STREAMS.md", "install.sh", "install-debian13.sh", "update.sh", "build.rs", "scripts/build/swagger_assets.py", "src/admin/documentation.rs", "src/admin/openapi.json", "langs/en_US.json", "langs/pl_pl.json", "Dockerfile", ".dockerignore", "docs/CONTAINER.md", "docs/PROMETHEUS.md", "docs/NOT_FOUND_HOSTS.md", "grafana/rustproxy-overview.json"]:
|
||||
if not (root / path).is_file():
|
||||
raise ValueError(f"Incomplete RustProxy 0.31.9 source tree: missing {path}")
|
||||
# The Reader uses compile-time include_str! for its bundled Markdown. A
|
||||
# dangling registration is a real compiler error, unlike an omitted old
|
||||
# release audit. Match both reader_doc! and the expanded include_str! form.
|
||||
registry = root / "src/admin/documentation/documents.rs"
|
||||
if not registry.is_file():
|
||||
raise ValueError("Incomplete RustProxy 0.31.9 source tree: missing src/admin/documentation/documents.rs")
|
||||
embedded_docs = set(re.findall(
|
||||
r'"(docs/[A-Za-z0-9_.-]+\.md)"', registry.read_text(encoding="utf-8")
|
||||
))
|
||||
for doc_path in sorted(embedded_docs):
|
||||
if not (root / doc_path).is_file():
|
||||
raise ValueError(f"Missing embedded Reader document: {doc_path}; restore the file or remove its Reader registration")
|
||||
text = (root / "src/lib.rs").read_text(encoding="utf-8")
|
||||
if '#[path = "auth/mod.rs"]' not in text:
|
||||
raise ValueError("src/lib.rs is not the 0.31.9 entry point; extract the complete package, not individual files.")
|
||||
return messages
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--root", type=Path, default=Path(__file__).resolve().parents[1])
|
||||
parser.add_argument("--repair-known", action="store_true")
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
for line in check(args.root.resolve(), args.repair_known):
|
||||
print(line, file=sys.stderr)
|
||||
except (OSError, ValueError) as error:
|
||||
parser.exit(2, f"Source preflight failed: {error}\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -7,14 +7,13 @@ if ! command -v cargo >/dev/null 2>&1 || ! command -v rustc >/dev/null 2>&1; the
|
||||
printf 'Rust 1.99+ and Cargo are required; no lockfile was regenerated.\n' >&2
|
||||
exit 127
|
||||
fi
|
||||
python3 tools/checks/preflight.py
|
||||
python3 scripts/preflight.py
|
||||
if [[ "$(python3 scripts/version.py)" != '0.31.8' ]]; then
|
||||
printf 'Expected RustProxy 0.31.8 sources.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
printf 'Toolchain: '; rustc --version
|
||||
cargo update
|
||||
python3 tools/checks/dependency_upgrade_0312.py --require-lock
|
||||
cargo metadata --locked --format-version 1 --no-deps >/dev/null
|
||||
cargo fmt --all -- --check
|
||||
cargo clippy --locked --all-targets -- -D warnings
|
||||
|
||||
Reference in new issue
Block a user