Commit graph

137 commits

Author SHA1 Message Date
Till Wegmueller
96b7207194 fix: Deduplicate FTS entries across catalog parts in build_shards
build_shards() iterates all three catalog parts (base, dependency,
summary) and each lists the same packages, causing every stem to be
inserted into the FTS index 3 times. Track seen stems in a HashSet
and skip duplicates. Fixes #22.
2026-04-09 22:18:15 +02:00
Till Wegmueller
f8ab1f94c1 fix: Resolve SHA1/SHA-256 hash mismatch in manifest lookups, complete search endpoints
fetch_manifest and the receiver were parsing legacy text manifests which
reference SHA1 hashes, while pkg5-imported repos store files under SHA-256.
Prefer the JSON manifest (.json) everywhere so payload lookups find the
correct files. Fixes archive creation, archive import, and local
FileBackend-to-FileBackend receive for pkg5-imported repositories.

Also completes the search REST API: v0 now returns 204 for empty results
per the pkg5 spec, and publisher-less routes (/search/0/, /search/1/) are
added for clients that omit the publisher prefix.
2026-04-09 22:06:48 +02:00
Till Wegmueller
4646d2a9c4 feat: Add .p6p archive format support for portable package distribution
Implement ArchiveBackend (read) and ArchiveWriter (create) using zip with
zstd compression. Adds archive/import-archive subcommands to pkg6repo and
.p6p source support to pkg6recv.
2026-04-03 13:21:36 +02:00
Till Wegmueller
9814635a32
feat: Preserve manifest text through install pipeline, add architecture plans
Manifest text is now carried through the solver's ResolvedPkg and written
directly to disk during install, eliminating the redundant re-fetch from
the repository that could silently fail. save_manifest() is now mandatory
(fatal on error) since the .p5m file on disk is the authoritative record
for pkg verify and pkg fix.

Add ADRs for libips API layer (GUI sharing), OpenID Connect auth, and
SQLite catalog as query engine (including normalized installed_actions
table). Add phase plans for code hygiene, client completion, catalog
expansion, and OIDC authentication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:28:10 +01:00
Till Wegmueller
d295a6e219
fix: Resolve merge conflict between UI and search compatibility branches
Merge both the UI handler (index, ui modules) and the legacy pkg5
search endpoint changes. Remove the obsolete JSON-based
build_search_index method since search now uses FTS5 via
sqlite_catalog::build_shards.
2026-03-23 17:27:36 +01:00
Till Wegmueller
6f5040978b fix: Deduplicate payload downloads to prevent parallel rename races
Multiple file actions in a manifest can reference the same payload hash.
When downloaded in parallel via rayon, multiple threads would write to
the same temp file path simultaneously, causing rename failures.

Now deduplicates payloads by digest before parallel download, then maps
results back to all file actions that reference each payload.
2026-03-15 21:14:35 +01:00
Till Wegmueller
bcea795848 fix: Store payloads under primary hash and fix digest detection
- Store compressed payloads under the primary (uncompressed) hash as
  the main key, matching IPS protocol where clients request files by
  the manifest's primary hash via /file/0/<hash>
- Create hardlink under compressed hash for internal lookups
- Detect SHA256 (64 chars) vs SHA1 (40 chars) from bare hex hash
  length in Digest::from_str instead of always defaulting to SHA1
- Remove digest verification for local file copies in FileBackend
  (files are compressed, hash is of uncompressed content)
- Simplify recv.rs payload fetch to use primary hash directly
  instead of trying multiple digest formats against the source
2026-03-15 20:58:44 +01:00
Till Wegmueller
a0fe229ba4 fix: Store payload files under both compressed and primary hash
Files were only stored under their compressed SHA256 hash, but pkg5
clients and the IPS protocol look up files by the manifest's primary
hash (typically SHA1/SHA256 uncompressed). Create a hardlink from the
primary hash path to the compressed hash file so both old and new
clients can find payloads via the server's /file/0/<hash> endpoint.
2026-03-15 20:44:43 +01:00
Till Wegmueller
0a28909e9e fix: Try raw hash before formatted digest in payload fetch fallback
The previous digest fallback used Display format (source:algorithm:hash)
which caused REST servers to look up files by SHA256 compressed hash
instead of the expected SHA1 primary hash. Now tries raw hash first
(compatible with pkg5 REST servers), then formatted variants with
algorithm info (compatible with local FileBackend storage).
2026-03-15 20:39:50 +01:00
Till Wegmueller
d5ed328ab2 fix: Resolve RwLock deadlocks in ObsoletedPackageManager causing test hangs
Multiple methods held a read or write lock on self.index while calling
fallback methods that also needed to acquire locks, causing deadlocks:

- get_obsoleted_package_metadata: read lock held during filesystem
  fallback that calls update_index_entry (write lock)
- get_obsoleted_package_manifest: same pattern
- remove_obsoleted_package: write lock held while calling build_index
  (also needs write lock)
- search_obsoleted_packages: read lock held during fallback

Fix: scope all lock acquisitions in blocks so locks are dropped before
calling any method that may also acquire a lock. For remove, extract a
needs_rebuild flag set inside the lock scope, then call build_index
after release.

All 95 libips tests now pass (previously 3 hung indefinitely).
2026-03-15 20:27:57 +01:00
Till Wegmueller
750df8dcc7 fix: Resolve pkg6recv multithreaded download race conditions and file loss
- Use tempdir_in(repo_path) instead of system /tmp to keep temp files on
  the same filesystem, preventing cross-device rename failures
- Replace fs::copy with fs::rename for atomic file moves in transaction
  commit and signature payload storage
- Fix Digest construction to use correct SHA256 algorithm instead of
  defaulting to SHA1 for bare hex hashes
- Try compressed hash (additional_identifiers) as fallback when primary
  hash lookup fails during payload fetch
- Remove duplicate publisher resolution block in Transaction::commit()
- Add integration test for multi-file parallel package receive

Closes: https://codeberg.org/Toasterson/ips/issues/21
2026-03-15 19:32:24 +01:00
Till Wegmueller
e83f2b7284
feat: Add full-text search via FTS5 and enable search endpoints
Add FTS5 search functions to sqlite_catalog (sanitize_fts_query,
search_fts, resolve_latest_fmris), enable search in versions response,
add integration tests, and remove legacy search code from file_backend.
2026-03-14 22:01:48 +01:00
Till Wegmueller
ac9ab8c447
feat: Enhance signature payload handling and add test coverage
- Made `receive_one` public to allow external use.
- Improved signature payload fetching, storing, and fallback logic for `FileBackend` repositories.
- Added test case `test_receive_with_signature` to verify signature handling and repository storage.
- Extended manifest fields in transaction logic to support additional attributes (e.g., `users`, `groups`, `drivers`).
- Updated `RestBackend` to handle extended file path lookups for signature payloads.
2026-02-06 00:40:59 +01:00
Till Wegmueller
e4f49cd7c8
Refactor: Introduce resolve_packages for wildcard handling and enhance repository package resolution
- Added `resolve_packages` to centralize wildcard pattern processing and match the latest package versions consistently.
- Updated both `FileBackend` and `RestBackend` to support wildcard patterns via `glob_to_regex` logic.
- Made `glob_to_regex` public to facilitate regex conversion for glob patterns.
- Improved `catalog_manager` handling in `RestBackend` by explicitly loading catalog parts to ensure accurate package matching.
- Replaced redundant FMRI parsing logic with `resolve_packages` for cleaner and more maintainable code.
2026-02-06 00:04:23 +01:00
Till Wegmueller
f8068364bc
Refactor: Replace direct signature fields with metadata-based storage
- Migrated `_SIGNATURE` handling in `CatalogPart`, `UpdateLog`, and `PackageUpdateEntry` to use metadata fields.
- Introduced `set_signature` and `signature` methods for cleaner access and manipulation of signature data.
- Updated deserialization logic to accommodate flattened metadata storage.
- Improved structure by centralizing signature and metadata interactions.
2026-02-05 23:34:15 +01:00
Till Wegmueller
7a3373a17d
Add detailed error handling for file and directory operations
- Introduced specific error variants (e.g., `FileOpenError`, `FileWriteError`, `DirectoryCreateError`) in `RepositoryError` for better error diagnostics.
- Applied `.map_err()` handling for operations like file creation, copying, renaming, and directory manipulation.
- Replaced direct `HashMap` usage with `Mutex<HashMap>` for thread-safe access to catalog managers in `RestBackend`.
- Refactored `list_packages` to use `list_packages_from_catalog`, removing reliance on the search API.
- Added temporary directory management for non-local-cache scenarios in `RestBackend`.
2026-02-05 23:16:02 +01:00
Till Wegmueller
dfc24725b8
Add signature handling for manifests
- Implemented support for fetching, importing, and storing signature payloads during transaction creation.
- Added the `Signature` struct to represent signature-related action data.
- Updated `Manifest` to include and process `signatures` as part of its fields.
- Enabled signature file imports with proper path resolution in `pkg6repo`.
2026-02-05 22:26:53 +01:00
Till Wegmueller
38baf16b6f
Refactor: Replace mutable repo assignments with immutable and enhance dependency action formatting
- Updated `FileBackend::open` calls to use immutable `repo` variables across multiple modules.
- Improved dependency action string construction by integrating optional properties, predicates, and facets for better clarity and flexibility.
2026-02-05 21:56:53 +01:00
Till Wegmueller
e236f30f6e
Convert trait methods to use &self instead of &mut self, introduce Mutex for interior mutability, optimize HTTP client creation, and implement parallel payload processing using Rayon. 2026-02-05 15:57:56 +01:00
Till Wegmueller
0de84b80c8
Refactor: Remove LZ4 compression utilities and clean up obsolete catalog functions
- Eliminated LZ4-based compression and related decoding utilities for manifest handling.
- Removed unused private helper and legacy methods in `catalog.rs`.
- Standardized database path handling, replacing `catalog_db_path` and `obsoleted_db_path` with `active_db_path` and `obsolete_db_path`.
- Added `#[allow(dead_code)]` annotations for unused methods in `file_backend.rs` to reduce warnings.
2026-02-04 23:03:20 +01:00
Till Wegmueller
7b9391f36e
Refactor: Remove unused imports and clean up redundant code
- Eliminated unused imports across multiple modules, including `info`, `trace`, `warn`, `base64`, `PathBuf`, and `fs`.
- Replaced mutable variable assignment with immutable in `populate_obsolete_db`.
- Simplified loop variable handling in `pkg6depotd` shard handler.
2026-02-04 22:47:44 +01:00
Till Wegmueller
240df1f5b9
chore(format): apply consistent code formatting across modules 2026-02-04 22:40:51 +01:00
Till Wegmueller
def11a1dfb
Refactor: Replace redb with rusqlite for catalog handling
- Transitioned the catalog backend from `redb` to `rusqlite` for better compatibility and concurrency.
- Updated `IpsProvider` to use SQLite for package querying, dependency resolution, and obsolescence handling.
- Removed `decode_manifest_bytes_local` and unused `manifest` cache logic.
- Simplified catalog-related functions and integrated `sqlite_catalog` module.
- Enhanced test functions and added schemas for managing SQLite databases.
2026-02-04 22:39:42 +01:00
Till Wegmueller
4ab529f4c7
chore(format): format code 2026-01-25 23:17:49 +01:00
Till Wegmueller
e1ce390abd
Refactor code to simplify handling and remove unused functions
- Removed `add_package` function from `FileBackend`, consolidating package indexing logic.
- Allowed unused assignments using `#![allow(unused_assignments)]` where necessary.
- Addressed unused imports in integration tests.
- Simplified `Digest` error handling by removing unreachable branches for unknown algorithms.
2026-01-20 22:19:25 +01:00
Till Wegmueller
1c0619ca55
Add pkg6recv package for receiving IPS repositories.
- Introduced `pkg6recv` for downloading packages from IPS repositories with support for recursive dependency fetching.
- Implemented CLI commands with `clap` for source/destination setup, package selection, and publisher defaults.
- Added `ConsoleProgressReporter` for detailed receive progress visibility.
- Enhanced the `Manifest` parser to support JSON format alongside IPS text format.
- Updated `FileBackend` and `RestBackend` repositories to fetch manifests and payloads in new operations.
- Extended `Digest` utilities for payload integrity checks.
- Added tests to verify basic functionality and manifest format preservation.
2026-01-20 20:16:58 +01:00
Till Wegmueller
22178cffd7
Add manual testing setup for pkg6depotd
- Introduced scripts and configurations for manual testing using `anyvm` with OpenIndiana and OmniOS.
- Implemented repository fetching (`fetch_repo.sh`) and server startup (`run_depotd.sh`) scripts.
- Enhanced `pkg6depotd` to support default publisher routes and trailing slashes.
- Updated integration tests to verify new publisher route behavior.
2026-01-20 17:44:36 +01:00
Till Wegmueller
6ee6392b01
Standardize description, version, authors, and edition fields across packages using workspace inheritance. 2026-01-19 00:25:47 +01:00
Till Wegmueller
898ec20ad8
Update binaries and workflows for pkg6 rename
- Renamed `pkg6dev` to `pkg6` across build scripts, workflows, and documentation.
- Added support for additional binaries (`pkg6repo` and `pkg6depotd`) in release builds.
- Disabled `RUSTFLAGS` warnings-as-errors policy in workflows for improved flexibility.
- Simplified error handling in `manifest_fmri` with streamlined conditionals.
- Introduced `#[allow(clippy::result_large_err)]` to suppress clippy warnings for large error types.
2026-01-18 14:30:05 +01:00
Till Wegmueller
b8c625a11e
Refactor attribute value access and error handling
- Replaced `values.get(0)` with `values.first()` for improved clarity and consistency across multiple files.
- Simplified conditional checks with `.is_empty()` and `format_args!` to enhance readability.
- Implemented `Default` trait for `VariableMode` directly within the enum.
- Updated error handling by boxing errors in `RepositoryError` and `CatalogError`.
- Replaced redundant `else` blocks with streamlined logic.
2026-01-18 13:00:21 +01:00
Till Wegmueller
9512eb3b12
chore: cargo fmt 2026-01-18 12:51:55 +01:00
Till Wegmueller
8f089656ba
Add search functionality to repository and route handlers (currently disabled)
- Introduced a searchable index with structured `IndexEntry` support for packages, files, directories, and dependencies.
- Added `search` method in `DepotRepo` with wildcard and case-sensitive query handling.
- Created `/search/0` and `/search/1` routes for search API, supporting publishers and token-based queries.
- Updated `SearchIndex` handling to map tokens to detailed `IndexEntry` structures.
- Improved index building to include attributes for files, directories, and dependencies.
2026-01-18 12:29:44 +01:00
Till Wegmueller
b080288114
Add legacy manifest handling with JSON fallback for transaction commits
- Introduced `legacy_manifest_content` field in `Transaction` to allow preserving byte-identical legacy manifests.
- Updated `commit` method to save both JSON and legacy manifests, falling back to JSON if no legacy content is provided.
- Enhanced manifest copy logic to handle both JSON and legacy formats during transaction finalization.
- Improved catalog rebuild to skip `.json` files when a corresponding legacy manifest exists.
2025-12-23 14:09:14 +01:00
Till Wegmueller
7dc475ed2d
Fix FMRI and catalog processing inconsistencies
- Corrected FMRI formatting to `pkg:/name` for entries without a publisher.
- Excluded `pkg.fmri` from summary action extraction in file backend.
- Removed unused signature handling in catalog package processing.
- Reordered `PackageVersionEntry` struct fields for logical consistency.
2025-12-23 13:19:51 +01:00
Till Wegmueller
b32ace705f
Refactor whitespace handling in JSON serialization and improve ISO-8601 timestamp formatting
- Removed unnecessary spaces in JSON key-value and array formatting for Python-style compatibility.
- Enhanced `format_iso8601_basic` to ensure precise microsecond-level time formatting.
- Updated `write_update_log` to return and store SHA-1 signatures for update log verification.
2025-12-23 12:33:12 +01:00
Till Wegmueller
ff0b9f4319
Add support for file URL without algorithm and refactor JSON serialization for Python-style compatibility
- Added `/file/1/{digest}` route to support file retrieval without specifying the algorithm.
- Implemented a Python-compatible JSON serializer to ensure consistent formatting for catalog artifacts.
- Replaced `HashMap` with `BTreeMap` for deterministic ordering in catalog serialization and updates.
- Updated integration tests to validate the new route functionality and ensure response correctness.
- Refactored `format_iso8601_basic` to improve timestamp formatting consistency.
2025-12-22 22:42:56 +01:00
Till Wegmueller
a921c99eb6
Reorder struct fields for consistency and align with Rust formatting standards. 2025-12-22 20:11:08 +01:00
Till Wegmueller
d2d1c297cc
Refactor to align with Rust formatting guidelines and enhance code readability.
- Adjusted indentation and line breaks for structs, functions, and method calls to comply with Rust formatting standards.
- Improved error message formatting and consistency across `PkgTreeError` instances.
- Restructured long function arguments and chained calls for clarity and maintainability.
- Simplified conditional statements and loops for better readability.
- No functional changes introduced.
2025-12-22 20:10:17 +01:00
Till Wegmueller
e87d1a3166
Add batched catalog rebuild support and INI-only repo test
- Introduced `BatchOptions` for configurable batched catalog rebuilds.
- Added `rebuild_catalog_batched` in `file_backend` for batched processing with deterministic package order and progress tracking.
- Updated `rebuild_catalog` to leverage the new batched implementation with default options.
- Added integration test `test_ini_only_repo_serving_catalog` to validate functionality with an INI-only repository configuration.
- Enhanced test coverage for legacy catalog handling via `pkg5.repository`.
2025-12-09 14:23:55 +01:00
Till Wegmueller
bd67e06012
Add catalog_writer module for atomic catalog updates with SHA-1 signatures
- Introduced `write_catalog_attrs`, `write_catalog_part`, and `write_update_log` functions for streamlined and secure file writing.
- Refactored `file_backend` to use `catalog_writer` for managing catalog updates, improving readability and maintainability.
- Updated `save_catalog_attrs`, `save_catalog_part`, and `append_update` to leverage atomic writes and ensure signature computation.
- Replaced manual serialization logic with centralized writing utilities for consistency and error resilience.
- Updated dependencies for JSON handling and signature computation.
2025-12-09 12:49:25 +01:00
Till Wegmueller
a948f87e6f
Add legacy repository support and SHA-1 signature handling
- Introduced fallback for legacy `pkg5.repository` configuration in INI format alongside the existing `pkg6.repository` JSON format.
- Enabled SHA-1 signature computation for compatibility with legacy catalog signatures.
- Added methods to save update logs in legacy format and enhance catalog compatibility.
- Updated dependencies to include `sha1` for hashing.
2025-12-09 12:12:57 +01:00
Till Wegmueller
c4910bb434
Refactor error handling in repository module to include structured error variants with detailed context.
- Replaced string-based `FileReadError`, `FileWriteError`, and `DirectoryCreateError` with structured error types using `PathBuf` and `source`.
- Updated all affected methods in `rest_backend`, `file_backend`, and tests to use the new structured error variants.
- Improved error messages for clarity and debugging by embedding file paths and sources directly into error data.
2025-12-08 23:13:27 +01:00
Till Wegmueller
81bc7b8574
Refactor catalog handling by replacing get_legacy_catalog with get_catalog_file_path for improved clarity and consistency.
- Removed now-redundant catalog path resolution logic in `repo.rs`.
- Updated `file_backend` with a unified method for fetching catalog file paths, addressing invalid path prefixes.
- Adjusted HTTP handler to use the updated method.
2025-12-08 22:45:39 +01:00
Till Wegmueller
55decc16ff
Simplify CatalogPart::load by removing manual JSON parsing fallbacks and introducing test coverage for sample catalogs. 2025-12-08 22:39:28 +01:00
Till Wegmueller
84b2c50ed6
Remove deprecated Catalog v0 support and refactor legacy catalog handling.
- Removed `get_catalog` handler and associated Catalog v0 route.
- Updated `get_legacy_catalog` to accept `filename` for enhanced flexibility.
- Adjusted integration tests to validate changes and focus on Catalog v1 support.
- Refactored `SupportedOperation` definitions to exclude Catalog v0.
2025-12-08 22:10:11 +01:00
Till Wegmueller
0b3a974ca6
Add REST API v1 endpoints and legacy catalog handling for pkg6depotd
- Expanded repository structure by introducing methods for fetching legacy catalogs, catalog file paths, and repository info.
- Added new REST API v1 endpoints for catalog, manifest, file, and publisher handling.
- Implemented `publisher` handler module with `get_publisher_v0` and `get_publisher_v1` methods to retrieve publisher details in pkg5 format.
- Updated `integration_tests` to validate new endpoints and ensure compatibility with legacy and modern catalog/manifest handling.
- Removed unused dependency `walkdir` and refactored test cases for clarity and efficiency.
2025-12-08 21:36:37 +01:00
Till Wegmueller
23815a2aab
Expand ManifestBuilder with new helper methods for setting attributes, licenses, links, and dependencies.
- Added `add_set`, `add_license`, `add_link`, and `add_depend` methods for streamlined manifest construction.
- Updated documentation with new examples showcasing the extended `ManifestBuilder` API.
- Enhanced test coverage to validate the new helper methods.
2025-08-31 00:17:15 +02:00
Till Wegmueller
d78cd9f659
Refactor depend module
- Simplified `split_dir_base` signature by removing unnecessary lifetime annotation.
- Refactored `compute_python_runpaths` to eliminate mutable variable and streamline `insert_default_runpath`.
2025-08-30 23:26:17 +02:00
Till Wegmueller
29ef35f350
Add api module for forge/pkgdev high-level integration
- Introduced `api.rs` to provide a stable, struct-first API surface for building, linting, resolving, and publishing IPS packages.
- Encapsulated existing functionality for better abstraction and usability in external integrations.
- Enhanced `libips` with a high-level repository and transaction interface.
- Added support for dependency generation, manifest transformations, and linting via configurable rulesets.
- Updated documentation with integration flow examples and usage guidelines.
2025-08-30 22:25:45 +02:00
Till Wegmueller
77f02fdfbd
Add depend module for file-level dependency generation
- Introduced `depend.rs` to handle dependency generation for ELF files, scripts, Python modules, and SMF manifests.
- Implemented file classification and analysis logic with configurable bypass rules and runpath handling.
- Added utility functions to resolve file dependencies into manifest actions using a provided repository.
- Updated `Cargo.toml` with `goblin` dependency for ELF processing.
- Enhanced codebase with default runpath insertion, dynamic token expansion, and Python module import detection.
- Included `pkgdepend` documentation for dependency resolution overview.
2025-08-30 18:35:41 +02:00