diff --git a/.woodpecker/build-rel.yml b/.woodpecker/build-rel.yml deleted file mode 100644 index faadd85..0000000 --- a/.woodpecker/build-rel.yml +++ /dev/null @@ -1,39 +0,0 @@ -matrix: - PLATFORM: - - 'linux/amd64' - -platform: ${PLATFORM} - -when: - branch: [main, dev] - event: [push, tag] - -steps: - build: - image: 'git.rustybever.be/chewing_bever/rieter-builder:1.79-alpine3.19' - commands: - - cargo build --verbose --release - - '[ "$(readelf -d target/release/rieterd | grep NEEDED | wc -l)" = 0 ]' - - publish-dev: - image: 'git.rustybever.be/chewing_bever/rieter-builder:1.79-alpine3.19' - commands: - - apk add --no-cache minio-client - - mcli alias set rb 'https://s3.rustybever.be' "$MINIO_ACCESS_KEY" "$MINIO_SECRET_KEY" - - mcli cp target/release/rieterd "rb/rieter/commits/$CI_COMMIT_SHA/rieterd-$(echo '${PLATFORM}' | sed 's:/:-:g')" - secrets: - - minio_access_key - - minio_secret_key - - publish-rel: - image: 'curlimages/curl' - commands: - - > - curl -s --fail - --user "Chewing_Bever:$GITEA_PASSWORD" - --upload-file target/release/rieterd - https://git.rustybever.be/api/packages/Chewing_Bever/generic/rieter/"${CI_COMMIT_TAG}"/rieterd-"$(echo '${PLATFORM}' | sed 's:/:-:g')" - secrets: - - gitea_password - when: - event: tag diff --git a/.woodpecker/build.yml b/.woodpecker/build.yml index f179f00..392bab1 100644 --- a/.woodpecker/build.yml +++ b/.woodpecker/build.yml @@ -2,20 +2,13 @@ platform: 'linux/amd64' when: branch: - exclude: [dev, main] + exclude: [main] event: push steps: build: - image: 'git.rustybever.be/chewing_bever/rieter-builder:1.79-alpine3.19' + image: 'rust:1.70-alpine3.18' commands: + - apk add --no-cache build-base libarchive libarchive-dev - cargo build --verbose - # Binaries, even debug ones, should be statically compiled - - '[ "$(readelf -d target/debug/rieterd | grep NEEDED | wc -l)" = 0 ]' - # Clippy also performs a full build, so putting it here saves the CI a - # lot of work - clippy: - image: 'git.rustybever.be/chewing_bever/rieter-builder:1.79-alpine3.19' - commands: - - cargo clippy -- --no-deps -Dwarnings diff --git a/.woodpecker/clippy.yml b/.woodpecker/clippy.yml new file mode 100644 index 0000000..b1c86a7 --- /dev/null +++ b/.woodpecker/clippy.yml @@ -0,0 +1,13 @@ +platform: 'linux/amd64' + +when: + branch: + exclude: [main] + event: push + +steps: + clippy: + image: 'rust:1.70-alpine3.18' + commands: + - rustup component add clippy + - cargo clippy -- --no-deps -Dwarnings diff --git a/.woodpecker/docker.yml b/.woodpecker/docker.yml index edba80c..0bcdf4a 100644 --- a/.woodpecker/docker.yml +++ b/.woodpecker/docker.yml @@ -1,11 +1,11 @@ platform: 'linux/amd64' when: - branch: [main, dev] - event: [push, tag] + branch: dev + event: push depends_on: - - build-rel + - build steps: dev: @@ -19,25 +19,4 @@ steps: tags: - 'dev' platforms: [ 'linux/amd64' ] - build_args_from_env: - - 'CI_COMMIT_SHA' mtu: 1300 - when: - branch: dev - event: push - - release: - image: 'woodpeckerci/plugin-docker-buildx' - secrets: - - 'docker_username' - - 'docker_password' - settings: - registry: 'git.rustybever.be' - repo: 'git.rustybever.be/chewing_bever/rieter' - auto_tag: true - platforms: [ 'linux/amd64' ] - build_args_from_env: - - 'CI_COMMIT_SHA' - mtu: 1300 - when: - event: tag diff --git a/.woodpecker/lint.yml b/.woodpecker/lint.yml index 2bd567e..4c09bc4 100644 --- a/.woodpecker/lint.yml +++ b/.woodpecker/lint.yml @@ -7,6 +7,7 @@ when: steps: lint: - image: 'git.rustybever.be/chewing_bever/rieter-builder:1.79-alpine3.19' + image: 'rust:1.70-alpine3.18' commands: + - rustup component add rustfmt - cargo fmt -- --check diff --git a/CHANGELOG.md b/CHANGELOG.md index 79a40d9..d9f4871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,15 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://git.rustybever.be/Chewing_Bever/rieter/src/branch/dev) -## [0.1.0](https://git.rustybever.be/Chewing_Bever/rieter/src/tag/0.1.0) - ### Added -* Functional repository server - * Supports any number of repositories, grouped into distros, each - supporting any number of architectures - * Repository & package information available using JSON REST API - * Queueing system with configurable number of workers for resilient - concurrency -* TOML configuration file -* SQLite & Postgres support +* Server + * Functional repository server + * Serve packages from any number of repositories & architectures + * Publish packages to and delete packages from repositories using HTTP + requests + * Packages of architecture "any" are part of every architecture's + database + * Bearer authentication for private routes + * REST API + * Repository & package information available using JSON REST API diff --git a/Cargo.lock b/Cargo.lock index bd0c194..a02d9ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.8" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ "getrandom", "once_cell", @@ -30,22 +30,21 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", "getrandom", "once_cell", "version_check", - "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -58,9 +57,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "android-tzdata" @@ -79,51 +78,51 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is_terminal_polyfill", + "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] @@ -151,18 +150,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] @@ -174,43 +173,26 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "autocfg" -version = "1.3.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.7.5" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" dependencies = [ "async-trait", "axum-core", - "axum-macros", + "bitflags 1.3.2", "bytes", "futures-util", "http", "http-body", - "http-body-util", "hyper", - "hyper-util", "itoa", "matchit", "memchr", @@ -222,52 +204,35 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper", "tokio", "tower", "tower-layer", "tower-service", - "tracing", ] [[package]] name = "axum-core" -version = "0.4.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes", "futures-util", "http", "http-body", - "http-body-util", "mime", - "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", "tower-layer", "tower-service", - "tracing", -] - -[[package]] -name = "axum-macros" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.66", ] [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", @@ -280,9 +245,15 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.7" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "base64ct" @@ -309,9 +280,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" dependencies = [ "serde", ] @@ -339,39 +310,60 @@ dependencies = [ [[package]] name = "borsh" -version = "1.5.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe5b10e214954177fb1dc9fbd20a1a2608fe99e6c832033bdc7cea287a20d77" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" dependencies = [ "borsh-derive", - "cfg_aliases", + "hashbrown 0.12.3", ] [[package]] name = "borsh-derive" -version = "1.5.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a8646f94ab393e43e8b35a2558b1624bed28b97ee09c5d15456e3c9463f46d" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" dependencies = [ - "once_cell", + "borsh-derive-internal", + "borsh-schema-derive-internal", "proc-macro-crate", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", - "syn_derive", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytecheck" -version = "0.6.12" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -380,38 +372,32 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.12" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", "syn 1.0.109", ] -[[package]] -name = "bytemuck" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" - [[package]] name = "byteorder" -version = "1.5.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.6.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.98" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -419,42 +405,38 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", + "time 0.1.45", "wasm-bindgen", - "windows-targets 0.52.5", + "winapi", ] [[package]] name = "clap" -version = "4.5.4" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" dependencies = [ "clap_builder", "clap_derive", + "once_cell", ] [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" dependencies = [ "anstream", "anstyle", @@ -464,78 +446,82 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "const-oid" -version = "0.9.6" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] [[package]] name = "crc" -version = "3.2.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" dependencies = [ "crc-catalog", ] [[package]] name = "crc-catalog" -version = "2.4.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" [[package]] name = "crossbeam-queue" -version = "0.3.11" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ + "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] [[package]] name = "crypto-common" @@ -549,25 +535,15 @@ dependencies = [ [[package]] name = "der" -version = "0.7.9" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" dependencies = [ "const-oid", "pem-rfc7468", "zeroize", ] -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", - "serde", -] - [[package]] name = "derivative" version = "2.2.0" @@ -599,9 +575,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "either" -version = "1.12.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" dependencies = [ "serde", ] @@ -614,12 +590,23 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", "libc", - "windows-sys 0.52.0", ] [[package]] @@ -630,7 +617,7 @@ checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" dependencies = [ "cfg-if", "home", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] @@ -641,32 +628,19 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - -[[package]] -name = "figment" -version = "0.10.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" -dependencies = [ - "atomic", - "pear", - "serde", - "toml", - "uncased", - "version_check", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "flume" -version = "0.11.0" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" dependencies = [ "futures-core", "futures-sink", + "pin-project", "spin 0.9.8", ] @@ -678,9 +652,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -693,9 +667,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -708,9 +682,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -718,15 +692,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -746,38 +720,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -803,20 +777,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "glob" @@ -826,17 +800,17 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.4.5" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ - "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", + "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -849,26 +823,26 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.8", + "ahash 0.7.6", ] [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.3", "allocator-api2", ] [[package]] name = "hashlink" -version = "0.8.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.14.0", ] [[package]] @@ -881,16 +855,19 @@ dependencies = [ ] [[package]] -name = "heck" -version = "0.5.0" +name = "hermit-abi" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] [[package]] name = "hermit-abi" -version = "0.3.9" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -900,9 +877,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ "hmac", ] @@ -918,18 +895,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "http" -version = "1.1.0" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -938,32 +915,20 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", "pin-project-lite", ] [[package]] name = "http-range-header" -version = "0.4.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" [[package]] name = "httparse" @@ -973,18 +938,19 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "1.3.1" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", + "futures-core", "futures-util", "h2", "http", @@ -993,37 +959,25 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "smallvec", - "tokio", -] - -[[package]] -name = "hyper-util" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d8d52be92d09acc2e01dddb7fde3ad983fc6489c7db4837e605bc3fca4cb63e" -dependencies = [ - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "pin-project-lite", + "socket2", "tokio", + "tower-service", + "tracing", + "want", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows", ] [[package]] @@ -1037,9 +991,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1047,57 +1001,66 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.14.0", ] [[package]] name = "inherent" -version = "1.0.11" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" +checksum = "ce243b1bfa62ffc028f1cc3b6034ec63d649f3031bc8a4fbbb004e1ac17d1f68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] -name = "inlinable_string" -version = "0.1.15" +name = "is-terminal" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi 0.3.2", + "rustix", + "windows-sys", +] [[package]] name = "itertools" -version = "0.12.1" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -1129,21 +1092,21 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.155" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" [[package]] name = "libsqlite3-sys" -version = "0.27.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" dependencies = [ "cc", "pkg-config", @@ -1152,15 +1115,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -1168,9 +1131,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "matchers" @@ -1183,25 +1146,24 @@ dependencies = [ [[package]] name = "matchit" -version = "0.7.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" [[package]] name = "md-5" -version = "0.10.6" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "cfg-if", "digest", ] [[package]] name = "memchr" -version = "2.7.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" @@ -1227,22 +1189,22 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.11" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi", - "windows-sys 0.48.0", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", ] [[package]] @@ -1267,10 +1229,11 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ + "autocfg", "num-integer", "num-traits", ] @@ -1292,26 +1255,21 @@ dependencies = [ "zeroize", ] -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ + "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ "autocfg", "num-integer", @@ -1320,9 +1278,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.19" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", "libm", @@ -1330,34 +1288,34 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "object" -version = "0.32.2" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "ordered-float" -version = "3.9.2" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +checksum = "2fc2dbde8f8a79f2102cc474ceb0ad68e3b80b85289ea62389b60e66777e4213" dependencies = [ "num-traits", ] @@ -1379,11 +1337,11 @@ version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] @@ -1394,9 +1352,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", "parking_lot_core", @@ -1404,45 +1362,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.1", + "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "paste" -version = "1.0.15" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pear" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" -dependencies = [ - "inlinable_string", - "pear_codegen", - "yansi", -] - -[[package]] -name = "pear_codegen" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.66", -] +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pem-rfc7468" @@ -1455,35 +1390,35 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -1514,15 +1449,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "ppv-lite86" @@ -1532,11 +1461,11 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml_edit 0.21.1", + "toml", ] [[package]] @@ -1565,26 +1494,13 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da" dependencies = [ "unicode-ident", ] -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", - "version_check", - "yansi", -] - [[package]] name = "ptr_meta" version = "0.1.4" @@ -1607,9 +1523,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1652,32 +1568,23 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" -dependencies = [ - "bitflags 2.5.0", -] - [[package]] name = "regex" -version = "1.10.5" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", - "regex-syntax 0.8.3", + "regex-automata 0.3.3", + "regex-syntax 0.7.4", ] [[package]] @@ -1691,13 +1598,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.3", + "regex-syntax 0.7.4", ] [[package]] @@ -1708,15 +1615,15 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "rend" -version = "0.4.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" dependencies = [ "bytecheck", ] @@ -1728,14 +1635,11 @@ dependencies = [ "axum", "chrono", "clap", - "figment", "futures", - "http-body-util", + "hyper", "libarchive", - "regex", "sea-orm", "sea-orm-migration", - "sea-query", "serde", "sha256", "tokio", @@ -1749,28 +1653,27 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.16.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ "cc", - "cfg-if", - "getrandom", "libc", - "spin 0.9.8", + "once_cell", + "spin 0.5.2", "untrusted", - "windows-sys 0.52.0", + "web-sys", + "winapi", ] [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ "bitvec", "bytecheck", - "bytes", "hashbrown 0.12.3", "ptr_meta", "rend", @@ -1782,9 +1685,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", @@ -1793,14 +1696,16 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.6" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ + "byteorder", "const-oid", "digest", "num-bigint-dig", "num-integer", + "num-iter", "num-traits", "pkcs1", "pkcs8", @@ -1813,12 +1718,13 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "4a2ab0025103a60ecaaf3abf24db1db240a4e1c15837090d2c32f625ac98abea" dependencies = [ "arrayvec", "borsh", + "byteorder", "bytes", "num-traits", "rand", @@ -1829,28 +1735,28 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.3.3", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "rustls" -version = "0.21.12" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" dependencies = [ "ring", "rustls-webpki", @@ -1859,18 +1765,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64", + "base64 0.21.2", ] [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.101.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" dependencies = [ "ring", "untrusted", @@ -1878,27 +1784,27 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "scopeguard" -version = "1.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "sct" -version = "0.7.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ "ring", "untrusted", @@ -1910,18 +1816,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bd3534a9978d0aa7edd2808dc1f8f31c4d0ecd31ddf71d997b3c98e9f3c9114" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "sea-orm" -version = "0.12.15" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8814e37dc25de54398ee62228323657520b7f29713b8e238649385dbe473ee0" +checksum = "90b508f060b689cd91abd76973ba4f1b0f416bb09915e2177fd3c6f853be76bc" dependencies = [ "async-stream", "async-trait", @@ -1939,7 +1845,7 @@ dependencies = [ "sqlx", "strum", "thiserror", - "time", + "time 0.3.23", "tracing", "url", "uuid", @@ -1947,9 +1853,9 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.12.15" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "620bc560062ae251b1366bde43b3f1508445cab5c2c8cbdb397034638ab1b357" +checksum = "7d3b389690bccc6565e6a6af367599957b196288c4f556a7b4157a8c5086eb8d" dependencies = [ "chrono", "clap", @@ -1964,23 +1870,23 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.12.15" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e115c6b078e013aa963cc2d38c196c2c40b05f03d0ac872fe06b6e0d5265603" +checksum = "8d49560a5a1bbd57f82fa1a622a8deefa51e44ce3a0b27f012f50bb6092a914f" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "sea-bae", - "syn 2.0.66", + "syn 2.0.25", "unicode-ident", ] [[package]] name = "sea-orm-migration" -version = "0.12.15" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee8269bc6ff71afd6b78aa4333ac237a69eebd2cdb439036291e64fb4b8db23c" +checksum = "fdccbb31e93d1a426a0df84f5f36d0b84d302444c3156e3a4fedb0b8da64ae87" dependencies = [ "async-trait", "clap", @@ -1995,9 +1901,9 @@ dependencies = [ [[package]] name = "sea-query" -version = "0.30.7" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4166a1e072292d46dc91f31617c2a1cdaf55a8be4b5c9f4bf2ba248e3ac4999b" +checksum = "6aeb899964df7038e7274306b742951b82a04f835bca8a4683a4c254a6bf35fa" dependencies = [ "bigdecimal", "chrono", @@ -2007,7 +1913,7 @@ dependencies = [ "rust_decimal", "sea-query-derive", "serde_json", - "time", + "time 0.3.23", "uuid", ] @@ -2023,28 +1929,28 @@ dependencies = [ "sea-query", "serde_json", "sqlx", - "time", + "time 0.3.23", "uuid", ] [[package]] name = "sea-query-derive" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a82fcb49253abcb45cdcb2adf92956060ec0928635eb21b4f7a6d8f25ab0bc" +checksum = "bd78f2e0ee8e537e9195d1049b752e0433e2cac125426bccb7b5c3e508096117" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", - "syn 2.0.66", + "syn 1.0.109", "thiserror", ] [[package]] name = "sea-schema" -version = "0.14.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d148608012d25222442d1ebbfafd1228dbc5221baf4ec35596494e27a2394e" +checksum = "c3e09eb40c78cee8fef8dfbb648036a26b7ad1f618499203ad0e8b6f97593f7f" dependencies = [ "futures", "sea-query", @@ -2057,7 +1963,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", "syn 1.0.109", @@ -2071,29 +1977,29 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "60363bdd39a7be0266a520dab25fdc9241d2f987b08a01e01f0ec6d06a981348" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "f28482318d6641454cb273da158647922d1be6b5a2fcc6165cd89ebdd7ed576b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -2102,23 +2008,14 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.16" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +checksum = "8acc4422959dd87a76cb117c191dcbffc20467f06c9100b76721dab370f24d3a" dependencies = [ "itoa", "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2133,9 +2030,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.6" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", @@ -2144,9 +2041,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if", "cpufeatures", @@ -2155,40 +2052,37 @@ dependencies = [ [[package]] name = "sha256" -version = "1.5.0" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" +checksum = "08a975c1bc0941703000eaf232c4d8ce188d8d5408d6344b6b2c8c6262772828" dependencies = [ - "async-trait", - "bytes", "hex", "sha2", - "tokio", ] [[package]] name = "sharded-slab" -version = "0.1.7" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ "lazy_static", ] [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] [[package]] name = "signature" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest", "rand_core", @@ -2202,27 +2096,27 @@ checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.13.2" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.5.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", - "windows-sys 0.52.0", + "winapi", ] [[package]] @@ -2242,9 +2136,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.3" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -2252,9 +2146,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" dependencies = [ "itertools", "nom", @@ -2263,9 +2157,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +checksum = "8e58421b6bc416714d5115a2ca953718f6c621a51b68e4f4922aea5a4391a721" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2276,11 +2170,11 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +checksum = "dd4cef4251aabbae751a3710927945901ee1d97ee96d757f6880ebb9a79bfd53" dependencies = [ - "ahash 0.8.11", + "ahash 0.8.3", "atoi", "bigdecimal", "byteorder", @@ -2288,6 +2182,7 @@ dependencies = [ "chrono", "crc", "crossbeam-queue", + "dotenvy", "either", "event-listener", "futures-channel", @@ -2297,7 +2192,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap", + "indexmap 2.0.0", "log", "memchr", "once_cell", @@ -2312,7 +2207,7 @@ dependencies = [ "smallvec", "sqlformat", "thiserror", - "time", + "time 0.3.23", "tokio", "tokio-stream", "tracing", @@ -2323,9 +2218,9 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +checksum = "208e3165167afd7f3881b16c1ef3f2af69fa75980897aac8874a0696516d12c2" dependencies = [ "proc-macro2", "quote", @@ -2336,13 +2231,13 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +checksum = "8a4a8336d278c62231d87f24e8a7a74898156e34c1c18942857be2acb29c7dfc" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck", "hex", "once_cell", "proc-macro2", @@ -2362,14 +2257,14 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" +checksum = "8ca69bf415b93b60b80dc8fda3cb4ef52b2336614d8da2de5456cc942a110482" dependencies = [ "atoi", - "base64", + "base64 0.21.2", "bigdecimal", - "bitflags 2.5.0", + "bitflags 2.3.3", "byteorder", "bytes", "chrono", @@ -2401,7 +2296,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", - "time", + "time 0.3.23", "tracing", "uuid", "whoami", @@ -2409,14 +2304,14 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" +checksum = "a0db2df1b8731c3651e204629dd55e52adbae0462fa1bdcbed56a2302c18181e" dependencies = [ "atoi", - "base64", + "base64 0.21.2", "bigdecimal", - "bitflags 2.5.0", + "bitflags 2.3.3", "byteorder", "chrono", "crc", @@ -2440,12 +2335,13 @@ dependencies = [ "rust_decimal", "serde", "serde_json", + "sha1", "sha2", "smallvec", "sqlx-core", "stringprep", "thiserror", - "time", + "time 0.3.23", "tracing", "uuid", "whoami", @@ -2453,9 +2349,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +checksum = "be4c21bf34c7cae5b283efb3ac1bcc7670df7561124dc2f8bdc0b59be40f79a2" dependencies = [ "atoi", "chrono", @@ -2470,10 +2366,9 @@ dependencies = [ "percent-encoding", "serde", "sqlx-core", - "time", + "time 0.3.23", "tracing", "url", - "urlencoding", "uuid", ] @@ -2485,20 +2380,19 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.5" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" dependencies = [ "unicode-bidi", "unicode-normalization", - "unicode-properties", ] [[package]] name = "strsim" -version = "0.11.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" @@ -2525,39 +2419,21 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "sync_wrapper" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "sync_wrapper" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" - [[package]] name = "tap" version = "1.0.1" @@ -2566,41 +2442,42 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ "cfg-if", "fastrand", + "redox_syscall", "rustix", - "windows-sys 0.52.0", + "windows-sys", ] [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ "cfg-if", "once_cell", @@ -2608,14 +2485,22 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ - "deranged", "itoa", - "num-conv", - "powerfmt", "serde", "time-core", "time-macros", @@ -2623,17 +2508,16 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ - "num-conv", "time-core", ] @@ -2654,10 +2538,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ + "autocfg", "backtrace", "bytes", "libc", @@ -2668,25 +2553,25 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", "pin-project-lite", @@ -2695,60 +2580,25 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", + "tracing", ] [[package]] name = "toml" -version = "0.8.14" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.22.14", -] - -[[package]] -name = "toml_datetime" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.6.13", ] [[package]] @@ -2769,17 +2619,17 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.5.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "a8bd22a874a2d0b70452d5597b12c537331d49060824a95f49f108994f94aa4c" dependencies = [ - "base64", - "bitflags 2.5.0", + "base64 0.20.0", + "bitflags 2.3.3", "bytes", + "futures-core", "futures-util", "http", "http-body", - "http-body-util", "http-range-header", "httpdate", "mime", @@ -2807,10 +2657,11 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ + "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -2819,20 +2670,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -2840,20 +2691,20 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.2.0" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ + "lazy_static", "log", - "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", @@ -2868,61 +2719,52 @@ dependencies = [ ] [[package]] -name = "typenum" -version = "1.17.0" +name = "try-lock" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] -name = "uncased" -version = "0.9.10" +name = "typenum" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "version_check", -] +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicase" -version = "2.7.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ "version_check", ] [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-properties" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" - [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode_categories" @@ -2932,27 +2774,21 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "untrusted" -version = "0.9.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.5.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] -[[package]] -name = "urlencoding" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" - [[package]] name = "utf8parse" version = "0.2.1" @@ -2961,9 +2797,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.8.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" dependencies = [ "getrandom", "serde", @@ -2987,23 +2823,32 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" - [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3011,24 +2856,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3036,38 +2881,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.25", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "webpki-roots" -version = "0.25.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" +dependencies = [ + "rustls-webpki", +] [[package]] name = "whoami" -version = "1.5.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" -dependencies = [ - "redox_syscall 0.4.1", - "wasite", -] +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" [[package]] name = "winapi" @@ -3092,12 +2946,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] @@ -3106,156 +2960,65 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" -dependencies = [ - "memchr", -] +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "wyz" @@ -3266,34 +3029,8 @@ dependencies = [ "tap", ] -[[package]] -name = "yansi" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" - -[[package]] -name = "zerocopy" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] - [[package]] name = "zeroize" -version = "1.8.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Dockerfile b/Dockerfile index e1e5a96..88b51a8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,16 @@ -FROM git.rustybever.be/chewing_bever/rieter-builder:1.79-alpine3.19 AS builder +FROM rust:1.70-alpine3.18 AS builder -ARG TARGETPLATFORM -ARG CI_COMMIT_SHA ARG DI_VER=1.2.5 WORKDIR /app RUN apk add --no-cache \ + build-base \ curl \ make \ unzip \ - pkgconf + pkgconf \ + libarchive libarchive-dev # Build dumb-init RUN curl -Lo - "https://github.com/Yelp/dumb-init/archive/refs/tags/v${DI_VER}.tar.gz" | tar -xzf - && \ @@ -21,17 +21,33 @@ RUN curl -Lo - "https://github.com/Yelp/dumb-init/archive/refs/tags/v${DI_VER}.t COPY . . -RUN curl \ - --fail \ - -o rieterd \ - "https://s3.rustybever.be/rieter/commits/${CI_COMMIT_SHA}/rieterd-$(echo "${TARGETPLATFORM}" | sed 's:/:-:g')" && \ - chmod +x rieterd +# ENV LIBARCHIVE_STATIC=1 \ +# LIBARCHIVE_LIB_DIR=/usr/lib \ +# LIBARCHIVE_INCLUDE_DIR=/usr/include \ +# LIBARCHIVE_LDFLAGS='-lssl -lcrypto -L/lib -lz -lbz2 -llzma -lexpat -lzstd -llz4' + # LIBARCHIVE_LDFLAGS='-L/usr/lib -lz -lbz2 -llzma -lexpat -lzstd -llz4 -lsqlite3' + +# https://users.rust-lang.org/t/sigsegv-with-program-linked-against-openssl-in-an-alpine-container/52172 +ENV RUSTFLAGS='-C target-feature=-crt-static' + +RUN cargo build --release && \ + du -h target/release/rieterd && \ + readelf -d target/release/rieterd && \ + chmod +x target/release/rieterd -FROM alpine:3.19 +FROM alpine:3.18 + +RUN apk add --no-cache \ + libgcc \ + libarchive \ + openssl COPY --from=builder /app/dumb-init /bin/dumb-init -COPY --from=builder /app/rieterd /bin/rieterd +COPY --from=builder /app/target/release/rieterd /bin/rieterd + +ENV RIETER_PKG_DIR=/data/pkgs \ + RIETER_DATA_DIR=/data WORKDIR /data diff --git a/README.md b/README.md index 1111131..3bdb5a4 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,2 @@ -# Rieter +# rieter -Rieter is both a Pacman repository server, as well as a build system for Pacman -packages. - -## Goals - -### Repository server - -My first goal for this project is to create a convenient all-round repository -server implementation that could be used for everything from self-hosting a -local repository to managing an entire distribution's package repository. It -should be easy to deploy, lightweight, and work with any distribution. It -should support any number of repositories and packages, and work with any -package architecture. - -The repositories can be populated by manually uploading packages to the server -(e.g. from a CI build), or by mirroring already existing repositories. The -mirroring feature in particular makes it trivial to set up a new mirror for a -distribution, as the server would take care of keeping the mirror up-to-date. -Another usecase for this would be creating a local mirror of your -distribution's repositories, which can greatly reduce your update times -depending on your internet connection. - -Most users however don't need a full copy of a distro's package repository, so -Rieter also provides a "smart mirror" mode. In this mode, a Rieter instance -only syncs packages that have been requested before, e.g. from a previous -system update. This way, your updates will still be a lot faster as the -required packages are cached, but packages you don't use don't get stored, -saving you a lot of storage space. - -### Build system - -The second goal is to create an easy-to-use build system for Pacman packages. -This could for example be used to automatically build AUR packages and publish -them to one of your repositories. This can greatly reduce update times, as you -no longer need to build AUR packages locally, as this automatically happens "in -the cloud". diff --git a/build.Dockerfile b/build.Dockerfile deleted file mode 100644 index 177b462..0000000 --- a/build.Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -# Command to build and push builder image (change tags as necessary): -# docker buildx build -f build.Dockerfile -t git.rustybever.be/chewing_bever/rieter-builder:1.79-alpine3.19 --platform linux/amd64,linux/arm64 --push . -FROM rust:1.79-alpine3.19 - -# Dependencies required to statically compile libarchive and libsqlite3 -RUN apk add --no-cache \ - build-base \ - libarchive-static libarchive-dev \ - zlib-static \ - openssl-libs-static \ - bzip2-static \ - xz-static \ - expat-static \ - zstd-static \ - lz4-static \ - acl-static && \ - rustup component add clippy rustfmt - -# Tell the libarchive3-sys package to statically link libarchive -ENV LIBARCHIVE_STATIC=1 diff --git a/libarchive/src/archive.rs b/libarchive/src/archive.rs index 932013b..97c9d0a 100644 --- a/libarchive/src/archive.rs +++ b/libarchive/src/archive.rs @@ -64,11 +64,11 @@ impl ReadFilter { pub fn extension(&self) -> Option<&str> { match self { ReadFilter::None => Some(""), - ReadFilter::Gzip => Some("gz"), - ReadFilter::Bzip2 => Some("bz2"), - ReadFilter::Lzma => Some("lzma"), - ReadFilter::Xz => Some("xz"), - ReadFilter::Zstd => Some("zst"), + ReadFilter::Gzip => Some(".gz"), + ReadFilter::Bzip2 => Some(".bz2"), + ReadFilter::Lzma => Some(".lzma"), + ReadFilter::Xz => Some(".xz"), + ReadFilter::Zstd => Some(".zst"), _ => None, } } @@ -386,7 +386,6 @@ pub enum ExtractOption { ClearNoChangeFFlags, } -#[derive(Default)] pub struct ExtractOptions { pub flags: i32, } @@ -421,3 +420,9 @@ impl ExtractOptions { self } } + +impl Default for ExtractOptions { + fn default() -> ExtractOptions { + ExtractOptions { flags: 0 } + } +} diff --git a/libarchive/src/read/builder.rs b/libarchive/src/read/builder.rs index 4af0401..e827130 100644 --- a/libarchive/src/read/builder.rs +++ b/libarchive/src/read/builder.rs @@ -78,7 +78,7 @@ impl Builder { ffi::archive_read_support_filter_program_signature( self.handle_mut(), c_prog.as_ptr(), - mem::transmute::, *const std::ffi::c_void>(cb), + mem::transmute(cb), size, ) } diff --git a/libarchive/src/write/builder.rs b/libarchive/src/write/builder.rs index b1cef46..b075284 100644 --- a/libarchive/src/write/builder.rs +++ b/libarchive/src/write/builder.rs @@ -11,8 +11,6 @@ pub struct Builder { consumed: bool, } -unsafe impl Send for Builder {} - impl Builder { pub fn new() -> Self { Builder::default() diff --git a/libarchive/src/write/file.rs b/libarchive/src/write/file.rs index ef4877d..5d932f1 100644 --- a/libarchive/src/write/file.rs +++ b/libarchive/src/write/file.rs @@ -2,12 +2,10 @@ use super::WriteEntry; use crate::error::ArchiveError; use crate::Entry; use crate::Handle; -use core::ffi::c_void; use libarchive3_sys::ffi; use std::fs; use std::io; use std::io::Read; -use std::io::Write; use std::path::Path; pub struct FileWriter { @@ -15,8 +13,6 @@ pub struct FileWriter { closed: bool, } -unsafe impl Send for FileWriter {} - impl Handle for FileWriter { unsafe fn handle(&self) -> *const ffi::Struct_archive { self.handle as *const _ @@ -35,22 +31,11 @@ impl FileWriter { } } - /// Append the given entry to the archive. After successfully calling this function, writing to - /// the archive now writes to this entry. - pub fn append_entry(&mut self, entry: &mut WriteEntry) -> crate::Result<()> { - unsafe { - match ffi::archive_write_header(self.handle_mut(), entry.entry_mut()) { - ffi::ARCHIVE_OK => Ok(()), - _ => Err(ArchiveError::from(self as &dyn Handle)), - } - } - } - pub fn append_data(&mut self, entry: &mut WriteEntry, r: &mut R) -> crate::Result<()> { unsafe { match ffi::archive_write_header(self.handle_mut(), entry.entry_mut()) { ffi::ARCHIVE_OK => (), - _ => return Err(ArchiveError::from(self as &dyn Handle)), + _ => return Err(ArchiveError::from(self as &dyn Handle).into()), } } @@ -74,7 +59,7 @@ impl FileWriter { // Negative values signal errors if res < 0 { - return Err(ArchiveError::from(self as &dyn Handle)); + return Err(ArchiveError::from(self as &dyn Handle).into()); } written += usize::try_from(res).unwrap(); @@ -122,23 +107,3 @@ impl Drop for FileWriter { } } } - -impl Write for FileWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - let res = unsafe { - ffi::archive_write_data(self.handle_mut(), buf.as_ptr() as *const c_void, buf.len()) - } as isize; - - if res < 0 { - Err(ArchiveError::from(self as &dyn Handle).into()) - } else { - // Unwrap is safe as we check if the value is negative in the if statement - Ok(res.try_into().unwrap()) - } - } - - fn flush(&mut self) -> io::Result<()> { - // Libarchive doesn't seem to provide a flush mechanism - Ok(()) - } -} diff --git a/libarchive/src/write/mod.rs b/libarchive/src/write/mod.rs index b64aadf..446edba 100644 --- a/libarchive/src/write/mod.rs +++ b/libarchive/src/write/mod.rs @@ -3,15 +3,12 @@ mod file; use crate::Entry; pub use builder::Builder; -pub use file::FileWriter; use libarchive3_sys::ffi; pub struct WriteEntry { entry: *mut ffi::Struct_archive_entry, } -unsafe impl Send for WriteEntry {} - impl WriteEntry { pub fn new() -> Self { let entry = unsafe { ffi::archive_entry_new() }; @@ -30,12 +27,6 @@ impl Entry for WriteEntry { } } -impl Default for WriteEntry { - fn default() -> Self { - Self::new() - } -} - impl Drop for WriteEntry { fn drop(&mut self) { unsafe { ffi::archive_entry_free(self.entry_mut()) } diff --git a/libarchive3-sys/README.md b/libarchive3-sys/README.md index a1467c0..bd605ef 100644 --- a/libarchive3-sys/README.md +++ b/libarchive3-sys/README.md @@ -4,7 +4,3 @@ DYLD_LIBRARY_PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib xcode-select --install - -# 64-bit timestamps - -`time_t` has been replaced with `i64` as Musl no longer supports 32-bit `time_t` values. diff --git a/libarchive3-sys/build.rs b/libarchive3-sys/build.rs index afe10d9..43d83e7 100644 --- a/libarchive3-sys/build.rs +++ b/libarchive3-sys/build.rs @@ -1,6 +1,35 @@ +extern crate pkg_config; + +use std::env; + fn main() { - pkg_config::Config::new() - .atleast_version("3") - .probe("libarchive") - .unwrap(); + let lib_dir = env::var("LIBARCHIVE_LIB_DIR").ok(); + let include_dir = env::var("LIBARCHIVE_INCLUDE_DIR").ok(); + + if lib_dir.is_some() && include_dir.is_some() { + println!("cargo:rustc-flags=-L native={}", lib_dir.unwrap()); + println!("cargo:include={}", include_dir.unwrap()); + let mode = match env::var_os("LIBARCHIVE_STATIC") { + Some(_) => "static", + None => "dylib", + }; + println!("cargo:rustc-flags=-l {0}=archive", mode); + + if mode == "static" { + if let Ok(ldflags) = env::var("LIBARCHIVE_LDFLAGS") { + for token in ldflags.split_whitespace() { + if token.starts_with("-L") { + println!("cargo:rustc-flags=-L native={}", token.replace("-L", "")); + } else if token.starts_with("-l") { + println!("cargo:rustc-flags=-l static={}", token.replace("-l", "")); + } + } + } + } + } else { + match pkg_config::find_library("libarchive") { + Ok(_) => (), + Err(msg) => panic!("Unable to locate libarchive, err={:?}", msg), + } + } } diff --git a/libarchive3-sys/src/ffi.rs b/libarchive3-sys/src/ffi.rs index f5ad4cf..92cd267 100644 --- a/libarchive3-sys/src/ffi.rs +++ b/libarchive3-sys/src/ffi.rs @@ -294,10 +294,14 @@ extern "C" { ) -> c_int; pub fn archive_read_extract_set_progress_callback( arg1: *mut Struct_archive, - _progress_func: ::std::option::Option, + _progress_func: ::std::option::Option ()>, _user_data: *mut c_void, - ); - pub fn archive_read_extract_set_skip_file(arg1: *mut Struct_archive, arg2: i64, arg3: i64); + ) -> (); + pub fn archive_read_extract_set_skip_file( + arg1: *mut Struct_archive, + arg2: i64, + arg3: i64, + ) -> (); pub fn archive_read_close(arg1: *mut Struct_archive) -> c_int; pub fn archive_read_free(arg1: *mut Struct_archive) -> c_int; pub fn archive_read_finish(arg1: *mut Struct_archive) -> c_int; @@ -439,7 +443,7 @@ extern "C" { arg3: ::std::option::Option< unsafe extern "C" fn(arg1: *mut c_void, arg2: *const c_char, arg3: i64) -> i64, >, - arg4: ::std::option::Option, + arg4: ::std::option::Option ()>, ) -> c_int; pub fn archive_write_disk_set_user_lookup( arg1: *mut Struct_archive, @@ -447,7 +451,7 @@ extern "C" { arg3: ::std::option::Option< unsafe extern "C" fn(arg1: *mut c_void, arg2: *const c_char, arg3: i64) -> i64, >, - arg4: ::std::option::Option, + arg4: ::std::option::Option ()>, ) -> c_int; pub fn archive_write_disk_gid(arg1: *mut Struct_archive, arg2: *const c_char, arg3: i64) -> i64; @@ -471,7 +475,7 @@ extern "C" { arg3: ::std::option::Option< unsafe extern "C" fn(arg1: *mut c_void, arg2: i64) -> *const c_char, >, - arg4: ::std::option::Option, + arg4: ::std::option::Option ()>, ) -> c_int; pub fn archive_read_disk_set_uname_lookup( arg1: *mut Struct_archive, @@ -479,7 +483,7 @@ extern "C" { arg3: ::std::option::Option< unsafe extern "C" fn(arg1: *mut c_void, arg2: i64) -> *const c_char, >, - arg4: ::std::option::Option, + arg4: ::std::option::Option ()>, ) -> c_int; pub fn archive_read_disk_open(arg1: *mut Struct_archive, arg2: *const c_char) -> c_int; pub fn archive_read_disk_open_w(arg1: *mut Struct_archive, arg2: *const wchar_t) -> c_int; @@ -498,7 +502,7 @@ extern "C" { arg1: *mut Struct_archive, arg2: *mut c_void, arg3: *mut Struct_archive_entry, - ), + ) -> (), >, _client_data: *mut c_void, ) -> c_int; @@ -525,9 +529,10 @@ extern "C" { pub fn archive_error_string(arg1: *mut Struct_archive) -> *const c_char; pub fn archive_format_name(arg1: *mut Struct_archive) -> *const c_char; pub fn archive_format(arg1: *mut Struct_archive) -> c_int; - pub fn archive_clear_error(arg1: *mut Struct_archive); - pub fn archive_set_error(arg1: *mut Struct_archive, _err: c_int, fmt: *const c_char, ...); - pub fn archive_copy_error(dest: *mut Struct_archive, src: *mut Struct_archive); + pub fn archive_clear_error(arg1: *mut Struct_archive) -> (); + pub fn archive_set_error(arg1: *mut Struct_archive, _err: c_int, fmt: *const c_char, ...) + -> (); + pub fn archive_copy_error(dest: *mut Struct_archive, src: *mut Struct_archive) -> (); pub fn archive_file_count(arg1: *mut Struct_archive) -> c_int; pub fn archive_match_new() -> *mut Struct_archive; pub fn archive_match_free(arg1: *mut Struct_archive) -> c_int; @@ -585,7 +590,7 @@ extern "C" { pub fn archive_match_include_time( arg1: *mut Struct_archive, _flag: c_int, - _sec: i64, + _sec: time_t, _nsec: c_long, ) -> c_int; pub fn archive_match_include_date( @@ -625,16 +630,16 @@ extern "C" { pub fn archive_match_include_gname_w(arg1: *mut Struct_archive, arg2: *const wchar_t) -> c_int; pub fn archive_entry_clear(arg1: *mut Struct_archive_entry) -> *mut Struct_archive_entry; pub fn archive_entry_clone(arg1: *mut Struct_archive_entry) -> *mut Struct_archive_entry; - pub fn archive_entry_free(arg1: *mut Struct_archive_entry); + pub fn archive_entry_free(arg1: *mut Struct_archive_entry) -> (); pub fn archive_entry_new() -> *mut Struct_archive_entry; pub fn archive_entry_new2(arg1: *mut Struct_archive) -> *mut Struct_archive_entry; - pub fn archive_entry_atime(arg1: *mut Struct_archive_entry) -> i64; + pub fn archive_entry_atime(arg1: *mut Struct_archive_entry) -> time_t; pub fn archive_entry_atime_nsec(arg1: *mut Struct_archive_entry) -> c_long; pub fn archive_entry_atime_is_set(arg1: *mut Struct_archive_entry) -> c_int; - pub fn archive_entry_birthtime(arg1: *mut Struct_archive_entry) -> i64; + pub fn archive_entry_birthtime(arg1: *mut Struct_archive_entry) -> time_t; pub fn archive_entry_birthtime_nsec(arg1: *mut Struct_archive_entry) -> c_long; pub fn archive_entry_birthtime_is_set(arg1: *mut Struct_archive_entry) -> c_int; - pub fn archive_entry_ctime(arg1: *mut Struct_archive_entry) -> i64; + pub fn archive_entry_ctime(arg1: *mut Struct_archive_entry) -> time_t; pub fn archive_entry_ctime_nsec(arg1: *mut Struct_archive_entry) -> c_long; pub fn archive_entry_ctime_is_set(arg1: *mut Struct_archive_entry) -> c_int; pub fn archive_entry_dev(arg1: *mut Struct_archive_entry) -> dev_t; @@ -646,7 +651,7 @@ extern "C" { arg1: *mut Struct_archive_entry, arg2: *mut c_ulong, arg3: *mut c_ulong, - ); + ) -> (); pub fn archive_entry_fflags_text(arg1: *mut Struct_archive_entry) -> *const c_char; pub fn archive_entry_gid(arg1: *mut Struct_archive_entry) -> i64; pub fn archive_entry_gname(arg1: *mut Struct_archive_entry) -> *const c_char; @@ -657,7 +662,7 @@ extern "C" { pub fn archive_entry_ino64(arg1: *mut Struct_archive_entry) -> i64; pub fn archive_entry_ino_is_set(arg1: *mut Struct_archive_entry) -> c_int; pub fn archive_entry_mode(arg1: *mut Struct_archive_entry) -> mode_t; - pub fn archive_entry_mtime(arg1: *mut Struct_archive_entry) -> i64; + pub fn archive_entry_mtime(arg1: *mut Struct_archive_entry) -> time_t; pub fn archive_entry_mtime_nsec(arg1: *mut Struct_archive_entry) -> c_long; pub fn archive_entry_mtime_is_set(arg1: *mut Struct_archive_entry) -> c_int; pub fn archive_entry_nlink(arg1: *mut Struct_archive_entry) -> c_uint; @@ -677,17 +682,33 @@ extern "C" { pub fn archive_entry_uid(arg1: *mut Struct_archive_entry) -> i64; pub fn archive_entry_uname(arg1: *mut Struct_archive_entry) -> *const c_char; pub fn archive_entry_uname_w(arg1: *mut Struct_archive_entry) -> *const wchar_t; - pub fn archive_entry_set_atime(arg1: *mut Struct_archive_entry, arg2: i64, arg3: c_long); - pub fn archive_entry_unset_atime(arg1: *mut Struct_archive_entry); - pub fn archive_entry_set_birthtime(arg1: *mut Struct_archive_entry, arg2: i64, arg3: c_long); - pub fn archive_entry_unset_birthtime(arg1: *mut Struct_archive_entry); - pub fn archive_entry_set_ctime(arg1: *mut Struct_archive_entry, arg2: i64, arg3: c_long); - pub fn archive_entry_unset_ctime(arg1: *mut Struct_archive_entry); - pub fn archive_entry_set_dev(arg1: *mut Struct_archive_entry, arg2: dev_t); - pub fn archive_entry_set_devmajor(arg1: *mut Struct_archive_entry, arg2: dev_t); - pub fn archive_entry_set_devminor(arg1: *mut Struct_archive_entry, arg2: dev_t); - pub fn archive_entry_set_filetype(arg1: *mut Struct_archive_entry, arg2: c_uint); - pub fn archive_entry_set_fflags(arg1: *mut Struct_archive_entry, arg2: c_ulong, arg3: c_ulong); + pub fn archive_entry_set_atime( + arg1: *mut Struct_archive_entry, + arg2: time_t, + arg3: c_long, + ) -> (); + pub fn archive_entry_unset_atime(arg1: *mut Struct_archive_entry) -> (); + pub fn archive_entry_set_birthtime( + arg1: *mut Struct_archive_entry, + arg2: time_t, + arg3: c_long, + ) -> (); + pub fn archive_entry_unset_birthtime(arg1: *mut Struct_archive_entry) -> (); + pub fn archive_entry_set_ctime( + arg1: *mut Struct_archive_entry, + arg2: time_t, + arg3: c_long, + ) -> (); + pub fn archive_entry_unset_ctime(arg1: *mut Struct_archive_entry) -> (); + pub fn archive_entry_set_dev(arg1: *mut Struct_archive_entry, arg2: dev_t) -> (); + pub fn archive_entry_set_devmajor(arg1: *mut Struct_archive_entry, arg2: dev_t) -> (); + pub fn archive_entry_set_devminor(arg1: *mut Struct_archive_entry, arg2: dev_t) -> (); + pub fn archive_entry_set_filetype(arg1: *mut Struct_archive_entry, arg2: c_uint) -> (); + pub fn archive_entry_set_fflags( + arg1: *mut Struct_archive_entry, + arg2: c_ulong, + arg3: c_ulong, + ) -> (); pub fn archive_entry_copy_fflags_text( arg1: *mut Struct_archive_entry, arg2: *const c_char, @@ -696,60 +717,79 @@ extern "C" { arg1: *mut Struct_archive_entry, arg2: *const wchar_t, ) -> *const wchar_t; - pub fn archive_entry_set_gid(arg1: *mut Struct_archive_entry, arg2: i64); - pub fn archive_entry_set_gname(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_gname(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_gname_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t); + pub fn archive_entry_set_gid(arg1: *mut Struct_archive_entry, arg2: i64) -> (); + pub fn archive_entry_set_gname(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_gname(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_gname_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t) -> (); pub fn archive_entry_update_gname_utf8( arg1: *mut Struct_archive_entry, arg2: *const c_char, ) -> c_int; - pub fn archive_entry_set_hardlink(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_hardlink(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_hardlink_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t); + pub fn archive_entry_set_hardlink(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_hardlink(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_hardlink_w( + arg1: *mut Struct_archive_entry, + arg2: *const wchar_t, + ) -> (); pub fn archive_entry_update_hardlink_utf8( arg1: *mut Struct_archive_entry, arg2: *const c_char, ) -> c_int; - pub fn archive_entry_set_ino(arg1: *mut Struct_archive_entry, arg2: i64); - pub fn archive_entry_set_ino64(arg1: *mut Struct_archive_entry, arg2: i64); - pub fn archive_entry_set_link(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_link(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_link_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t); + pub fn archive_entry_set_ino(arg1: *mut Struct_archive_entry, arg2: i64) -> (); + pub fn archive_entry_set_ino64(arg1: *mut Struct_archive_entry, arg2: i64) -> (); + pub fn archive_entry_set_link(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_link(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_link_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t) -> (); pub fn archive_entry_update_link_utf8( arg1: *mut Struct_archive_entry, arg2: *const c_char, ) -> c_int; - pub fn archive_entry_set_mode(arg1: *mut Struct_archive_entry, arg2: mode_t); - pub fn archive_entry_set_mtime(arg1: *mut Struct_archive_entry, arg2: i64, arg3: c_long); - pub fn archive_entry_unset_mtime(arg1: *mut Struct_archive_entry); - pub fn archive_entry_set_nlink(arg1: *mut Struct_archive_entry, arg2: c_uint); - pub fn archive_entry_set_pathname(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_pathname(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_pathname_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t); + pub fn archive_entry_set_mode(arg1: *mut Struct_archive_entry, arg2: mode_t) -> (); + pub fn archive_entry_set_mtime( + arg1: *mut Struct_archive_entry, + arg2: time_t, + arg3: c_long, + ) -> (); + pub fn archive_entry_unset_mtime(arg1: *mut Struct_archive_entry) -> (); + pub fn archive_entry_set_nlink(arg1: *mut Struct_archive_entry, arg2: c_uint) -> (); + pub fn archive_entry_set_pathname(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_pathname(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_pathname_w( + arg1: *mut Struct_archive_entry, + arg2: *const wchar_t, + ) -> (); pub fn archive_entry_update_pathname_utf8( arg1: *mut Struct_archive_entry, arg2: *const c_char, ) -> c_int; - pub fn archive_entry_set_perm(arg1: *mut Struct_archive_entry, arg2: mode_t); - pub fn archive_entry_set_rdev(arg1: *mut Struct_archive_entry, arg2: dev_t); - pub fn archive_entry_set_rdevmajor(arg1: *mut Struct_archive_entry, arg2: dev_t); - pub fn archive_entry_set_rdevminor(arg1: *mut Struct_archive_entry, arg2: dev_t); - pub fn archive_entry_set_size(arg1: *mut Struct_archive_entry, arg2: i64); - pub fn archive_entry_unset_size(arg1: *mut Struct_archive_entry); - pub fn archive_entry_copy_sourcepath(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_sourcepath_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t); - pub fn archive_entry_set_symlink(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_symlink(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_symlink_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t); + pub fn archive_entry_set_perm(arg1: *mut Struct_archive_entry, arg2: mode_t) -> (); + pub fn archive_entry_set_rdev(arg1: *mut Struct_archive_entry, arg2: dev_t) -> (); + pub fn archive_entry_set_rdevmajor(arg1: *mut Struct_archive_entry, arg2: dev_t) -> (); + pub fn archive_entry_set_rdevminor(arg1: *mut Struct_archive_entry, arg2: dev_t) -> (); + pub fn archive_entry_set_size(arg1: *mut Struct_archive_entry, arg2: i64) -> (); + pub fn archive_entry_unset_size(arg1: *mut Struct_archive_entry) -> (); + pub fn archive_entry_copy_sourcepath( + arg1: *mut Struct_archive_entry, + arg2: *const c_char, + ) -> (); + pub fn archive_entry_copy_sourcepath_w( + arg1: *mut Struct_archive_entry, + arg2: *const wchar_t, + ) -> (); + pub fn archive_entry_set_symlink(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_symlink(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_symlink_w( + arg1: *mut Struct_archive_entry, + arg2: *const wchar_t, + ) -> (); pub fn archive_entry_update_symlink_utf8( arg1: *mut Struct_archive_entry, arg2: *const c_char, ) -> c_int; - pub fn archive_entry_set_uid(arg1: *mut Struct_archive_entry, arg2: i64); - pub fn archive_entry_set_uname(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_uname(arg1: *mut Struct_archive_entry, arg2: *const c_char); - pub fn archive_entry_copy_uname_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t); + pub fn archive_entry_set_uid(arg1: *mut Struct_archive_entry, arg2: i64) -> (); + pub fn archive_entry_set_uname(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_uname(arg1: *mut Struct_archive_entry, arg2: *const c_char) -> (); + pub fn archive_entry_copy_uname_w(arg1: *mut Struct_archive_entry, arg2: *const wchar_t) -> (); pub fn archive_entry_update_uname_utf8( arg1: *mut Struct_archive_entry, arg2: *const c_char, @@ -757,7 +797,7 @@ extern "C" { // pub fn archive_entry_stat(arg1: *mut Struct_archive_entry) -> *const Struct_stat; // pub fn archive_entry_copy_stat(arg1: *mut Struct_archive_entry, // arg2: *const Struct_stat) - // ; + // -> (); pub fn archive_entry_mac_metadata( arg1: *mut Struct_archive_entry, arg2: *mut size_t, @@ -766,8 +806,8 @@ extern "C" { arg1: *mut Struct_archive_entry, arg2: *const c_void, arg3: size_t, - ); - pub fn archive_entry_acl_clear(arg1: *mut Struct_archive_entry); + ) -> (); + pub fn archive_entry_acl_clear(arg1: *mut Struct_archive_entry) -> (); pub fn archive_entry_acl_add_entry( arg1: *mut Struct_archive_entry, arg2: c_int, @@ -808,13 +848,13 @@ extern "C" { pub fn archive_entry_acl_text(arg1: *mut Struct_archive_entry, arg2: c_int) -> *const c_char; pub fn archive_entry_acl_count(arg1: *mut Struct_archive_entry, arg2: c_int) -> c_int; pub fn archive_entry_acl(arg1: *mut Struct_archive_entry) -> *mut Struct_archive_acl; - pub fn archive_entry_xattr_clear(arg1: *mut Struct_archive_entry); + pub fn archive_entry_xattr_clear(arg1: *mut Struct_archive_entry) -> (); pub fn archive_entry_xattr_add_entry( arg1: *mut Struct_archive_entry, arg2: *const c_char, arg3: *const c_void, arg4: size_t, - ); + ) -> (); pub fn archive_entry_xattr_count(arg1: *mut Struct_archive_entry) -> c_int; pub fn archive_entry_xattr_reset(arg1: *mut Struct_archive_entry) -> c_int; pub fn archive_entry_xattr_next( @@ -823,8 +863,12 @@ extern "C" { arg3: *mut *const c_void, arg4: *mut size_t, ) -> c_int; - pub fn archive_entry_sparse_clear(arg1: *mut Struct_archive_entry); - pub fn archive_entry_sparse_add_entry(arg1: *mut Struct_archive_entry, arg2: i64, arg3: i64); + pub fn archive_entry_sparse_clear(arg1: *mut Struct_archive_entry) -> (); + pub fn archive_entry_sparse_add_entry( + arg1: *mut Struct_archive_entry, + arg2: i64, + arg3: i64, + ) -> (); pub fn archive_entry_sparse_count(arg1: *mut Struct_archive_entry) -> c_int; pub fn archive_entry_sparse_reset(arg1: *mut Struct_archive_entry) -> c_int; pub fn archive_entry_sparse_next( @@ -836,13 +880,13 @@ extern "C" { pub fn archive_entry_linkresolver_set_strategy( arg1: *mut Struct_archive_entry_linkresolver, arg2: c_int, - ); - pub fn archive_entry_linkresolver_free(arg1: *mut Struct_archive_entry_linkresolver); + ) -> (); + pub fn archive_entry_linkresolver_free(arg1: *mut Struct_archive_entry_linkresolver) -> (); pub fn archive_entry_linkify( arg1: *mut Struct_archive_entry_linkresolver, arg2: *mut *mut Struct_archive_entry, arg3: *mut *mut Struct_archive_entry, - ); + ) -> (); pub fn archive_entry_partial_links( res: *mut Struct_archive_entry_linkresolver, links: *mut c_uint, diff --git a/server/Cargo.toml b/server/Cargo.toml index 5c26303..0bdfee3 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -7,22 +7,19 @@ authors = ["Jef Roosens"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axum = { version = "0.7.5", features = ["http2", "macros"] } +axum = { version = "0.6.18", features = ["http2"] } +hyper = "*" chrono = { version = "0.4.26", features = ["serde"] } clap = { version = "4.3.12", features = ["env", "derive"] } -figment = { version = "0.10.19", features = ["env", "toml"] } futures = "0.3.28" -http-body-util = "0.1.1" libarchive = { path = "../libarchive" } -regex = "1.10.5" sea-orm-migration = "0.12.1" -sea-query = { version = "0.30.7", features = ["backend-postgres", "backend-sqlite"] } serde = { version = "1.0.178", features = ["derive"] } sha256 = "1.1.4" tokio = { version = "1.29.1", features = ["full"] } tokio-util = { version = "0.7.8", features = ["io"] } tower = { version = "0.4.13", features = ["make"] } -tower-http = { version = "0.5.2", features = ["fs", "trace", "auth"] } +tower-http = { version = "0.4.1", features = ["fs", "trace", "auth"] } tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } uuid = { version = "1.4.0", features = ["v4"] } @@ -34,6 +31,5 @@ features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", - "with-chrono", - "debug-print" + "with-chrono" ] diff --git a/server/rieterd.toml b/server/rieterd.toml deleted file mode 100644 index 9cc56bf..0000000 --- a/server/rieterd.toml +++ /dev/null @@ -1,17 +0,0 @@ -api_key = "test" -pkg_workers = 2 -log_level = "rieterd=debug" - -[fs] -type = "local" -data_dir = "./data" - -[db] -type = "sqlite" -db_dir = "./data" -# [db] -# type = "postgres" -# host = "localhost" -# db = "rieter" -# user = "rieter" -# password = "rieter" diff --git a/server/src/cli.rs b/server/src/cli.rs index 5e8469e..ec93f8b 100644 --- a/server/src/cli.rs +++ b/server/src/cli.rs @@ -1,15 +1,101 @@ -use std::path::PathBuf; +use crate::repo::RepoGroupManager; +use crate::{Config, Global}; +use axum::extract::FromRef; use clap::Parser; +use std::io; +use std::path::PathBuf; +use std::sync::{Arc, RwLock}; +use tracing::debug; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; #[derive(Parser)] #[command(author, version, about, long_about = None)] pub struct Cli { + /// Directory where package archives will be stored + #[arg(env = "RIETER_PKG_DIR")] + pub pkg_dir: PathBuf, + /// Directory where repository metadata & SQLite database is stored + #[arg(env = "RIETER_DATA_DIR")] + pub data_dir: PathBuf, + /// API key to authenticate private routes with + #[arg(env = "RIETER_API_KEY")] + pub api_key: String, + + /// Database connection URL; either sqlite:// or postgres://. Defaults to rieter.sqlite in the + /// data directory + #[arg(short, long, env = "RIETER_DATABASE_URL")] + pub database_url: Option, + /// Port the server will listen on #[arg( short, long, - env = "RIETER_CONFIG_FILE", - default_value = "./rieterd.toml" + value_name = "PORT", + default_value_t = 8000, + env = "RIETER_PORT" )] - pub config_file: PathBuf, + pub port: u16, + /// Log levels for the tracing + #[arg( + long, + value_name = "LOG_LEVEL", + default_value = "tower_http=debug,rieterd=debug", + env = "RIETER_LOG" + )] + pub log: String, +} + +impl FromRef for Arc> { + fn from_ref(global: &Global) -> Self { + Arc::clone(&global.repo_manager) + } +} + +impl Cli { + pub fn init_tracing(&self) { + tracing_subscriber::registry() + .with(tracing_subscriber::EnvFilter::new(self.log.clone())) + .with(tracing_subscriber::fmt::layer()) + .init(); + } + + pub async fn run(&self) -> crate::Result<()> { + self.init_tracing(); + + let db_url = if let Some(url) = &self.database_url { + url.clone() + } else { + format!( + "sqlite://{}", + self.data_dir.join("rieter.sqlite").to_string_lossy() + ) + }; + + debug!("Connecting to database with URL {}", db_url); + + let db = crate::db::RieterDb::connect(db_url).await?; + // let db = crate::db::init("postgres://rieter:rieter@localhost:5432/rieter") + // .await + // .unwrap(); + + let config = Config { + data_dir: self.data_dir.clone(), + repo_dir: self.data_dir.join("repos"), + pkg_dir: self.pkg_dir.clone(), + api_key: self.api_key.clone(), + }; + let repo_manager = RepoGroupManager::new(&config.repo_dir, &self.pkg_dir); + + let global = Global { + config, + repo_manager: Arc::new(RwLock::new(repo_manager)), + db, + }; + + // build our application with a single route + let app = crate::web::app(global, &self.api_key); + Ok(crate::web::serve(app, self.port) + .await + .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?) + } } diff --git a/server/src/config.rs b/server/src/config.rs deleted file mode 100644 index e165fdc..0000000 --- a/server/src/config.rs +++ /dev/null @@ -1,88 +0,0 @@ -use std::path::{Path, PathBuf}; - -use figment::{ - providers::{Env, Format, Toml}, - Figment, -}; -use serde::Deserialize; - -#[derive(Deserialize, Debug, Clone)] -#[serde(rename_all = "lowercase")] -#[serde(tag = "type")] -pub enum FsConfig { - Local { data_dir: PathBuf }, -} - -#[derive(Deserialize, Debug, Clone)] -#[serde(rename_all = "lowercase")] -#[serde(tag = "type")] -pub enum DbConfig { - Sqlite { - db_dir: PathBuf, - #[serde(default = "default_db_sqlite_max_connections")] - max_connections: u32, - }, - Postgres { - host: String, - #[serde(default = "default_db_postgres_port")] - port: u16, - user: String, - password: String, - db: String, - #[serde(default)] - schema: String, - #[serde(default = "default_db_postgres_max_connections")] - max_connections: u32, - }, -} - -#[derive(Deserialize, Debug, Clone)] -pub struct Config { - pub api_key: String, - #[serde(default = "default_domain")] - pub domain: String, - #[serde(default = "default_port")] - pub port: u16, - #[serde(default = "default_log_level")] - pub log_level: String, - pub fs: FsConfig, - pub db: DbConfig, - #[serde(default = "default_pkg_workers")] - pub pkg_workers: u32, -} - -impl Config { - pub fn figment(config_file: impl AsRef) -> Figment { - Figment::new() - .merge(Toml::file(config_file)) - .merge(Env::prefixed("RIETER_")) - } -} - -fn default_domain() -> String { - String::from("0.0.0.0") -} - -fn default_port() -> u16 { - 8000 -} - -fn default_log_level() -> String { - String::from("tower_http=debug,rieterd=debug,sea_orm=debug") -} - -fn default_db_sqlite_max_connections() -> u32 { - 16 -} - -fn default_db_postgres_port() -> u16 { - 5432 -} - -fn default_db_postgres_max_connections() -> u32 { - 16 -} - -fn default_pkg_workers() -> u32 { - 1 -} diff --git a/server/src/db/conn.rs b/server/src/db/conn.rs new file mode 100644 index 0000000..2756236 --- /dev/null +++ b/server/src/db/conn.rs @@ -0,0 +1,61 @@ +use super::RieterDb; +use sea_orm::{DbBackend, DbErr, ExecResult, QueryResult, Statement}; +use std::{future::Future, pin::Pin}; + +// Allows RieterDb objects to be passed to ORM functions +impl sea_orm::ConnectionTrait for RieterDb { + fn get_database_backend(&self) -> DbBackend { + self.conn.get_database_backend() + } + fn execute<'life0, 'async_trait>( + &'life0 self, + stmt: Statement, + ) -> Pin> + Send + 'async_trait>> + where + Self: 'async_trait, + 'life0: 'async_trait, + { + self.conn.execute(stmt) + } + fn execute_unprepared<'life0, 'life1, 'async_trait>( + &'life0 self, + sql: &'life1 str, + ) -> Pin> + Send + 'async_trait>> + where + Self: 'async_trait, + 'life0: 'async_trait, + 'life1: 'async_trait, + { + self.conn.execute_unprepared(sql) + } + fn query_one<'life0, 'async_trait>( + &'life0 self, + stmt: Statement, + ) -> Pin< + Box< + dyn Future, DbErr>> + + Send + + 'async_trait, + >, + > + where + Self: 'async_trait, + 'life0: 'async_trait, + { + self.conn.query_one(stmt) + } + fn query_all<'life0, 'async_trait>( + &'life0 self, + stmt: Statement, + ) -> Pin< + Box< + dyn Future, DbErr>> + Send + 'async_trait, + >, + > + where + Self: 'async_trait, + 'life0: 'async_trait, + { + self.conn.query_all(stmt) + } +} diff --git a/server/src/db/entities/distro.rs b/server/src/db/entities/distro.rs index f39ad53..835cba5 100644 --- a/server/src/db/entities/distro.rs +++ b/server/src/db/entities/distro.rs @@ -7,9 +7,14 @@ use serde::{Deserialize, Serialize}; #[sea_orm(table_name = "distro")] pub struct Model { #[sea_orm(primary_key)] + #[serde(skip_deserializing)] pub id: i32, + #[sea_orm(unique)] + pub slug: String, + #[sea_orm(unique)] pub name: String, pub description: Option, + pub url: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/server/src/db/entities/mod.rs b/server/src/db/entities/mod.rs index b38dbb1..96603bf 100644 --- a/server/src/db/entities/mod.rs +++ b/server/src/db/entities/mod.rs @@ -4,8 +4,11 @@ pub mod prelude; pub mod distro; pub mod package; +pub mod package_conflicts; +pub mod package_depends; pub mod package_file; pub mod package_group; pub mod package_license; -pub mod package_related; +pub mod package_provides; +pub mod package_replaces; pub mod repo; diff --git a/server/src/db/entities/package.rs b/server/src/db/entities/package.rs index 4ef90a4..b2e2b0b 100644 --- a/server/src/db/entities/package.rs +++ b/server/src/db/entities/package.rs @@ -1,11 +1,8 @@ //! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 -use chrono::NaiveDateTime; use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; -use crate::db::PackageState; - #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[sea_orm(table_name = "package")] pub struct Model { @@ -20,26 +17,29 @@ pub struct Model { pub c_size: i64, pub description: Option, pub url: Option, - pub build_date: NaiveDateTime, + pub build_date: DateTime, pub packager: Option, pub pgp_sig: Option, pub pgp_sig_size: Option, pub sha256_sum: String, - pub compression: String, - #[serde(skip_serializing)] - pub state: PackageState, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] pub enum Relation { + #[sea_orm(has_many = "super::package_conflicts::Entity")] + PackageConflicts, + #[sea_orm(has_many = "super::package_depends::Entity")] + PackageDepends, #[sea_orm(has_many = "super::package_file::Entity")] PackageFile, #[sea_orm(has_many = "super::package_group::Entity")] PackageGroup, #[sea_orm(has_many = "super::package_license::Entity")] PackageLicense, - #[sea_orm(has_many = "super::package_related::Entity")] - PackageRelated, + #[sea_orm(has_many = "super::package_provides::Entity")] + PackageProvides, + #[sea_orm(has_many = "super::package_replaces::Entity")] + PackageReplaces, #[sea_orm( belongs_to = "super::repo::Entity", from = "Column::RepoId", @@ -50,6 +50,18 @@ pub enum Relation { Repo, } +impl Related for Entity { + fn to() -> RelationDef { + Relation::PackageConflicts.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PackageDepends.def() + } +} + impl Related for Entity { fn to() -> RelationDef { Relation::PackageFile.def() @@ -68,9 +80,15 @@ impl Related for Entity { } } -impl Related for Entity { +impl Related for Entity { fn to() -> RelationDef { - Relation::PackageRelated.def() + Relation::PackageProvides.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PackageReplaces.def() } } diff --git a/server/src/db/entities/package_conflicts.rs b/server/src/db/entities/package_conflicts.rs new file mode 100644 index 0000000..e9e8ba8 --- /dev/null +++ b/server/src/db/entities/package_conflicts.rs @@ -0,0 +1,33 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 + +use sea_orm::entity::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[sea_orm(table_name = "package_conflicts")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub package_id: i32, + #[sea_orm(primary_key, auto_increment = false)] + pub value: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::package::Entity", + from = "Column::PackageId", + to = "super::package::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Package, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Package.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/server/src/db/entities/package_related.rs b/server/src/db/entities/package_depends.rs similarity index 86% rename from server/src/db/entities/package_related.rs rename to server/src/db/entities/package_depends.rs index 7241c1a..7e94374 100644 --- a/server/src/db/entities/package_related.rs +++ b/server/src/db/entities/package_depends.rs @@ -3,17 +3,15 @@ use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; -use crate::db::PackageRelatedEnum; - #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] -#[sea_orm(table_name = "package_related")] +#[sea_orm(table_name = "package_depends")] pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub package_id: i32, #[sea_orm(primary_key, auto_increment = false)] - pub r#type: PackageRelatedEnum, + pub r#type: crate::db::PackageDepend, #[sea_orm(primary_key, auto_increment = false)] - pub name: String, + pub value: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/server/src/db/entities/package_file.rs b/server/src/db/entities/package_file.rs index 8607cf8..6e994e0 100644 --- a/server/src/db/entities/package_file.rs +++ b/server/src/db/entities/package_file.rs @@ -9,7 +9,7 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub package_id: i32, #[sea_orm(primary_key, auto_increment = false)] - pub path: String, + pub value: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/server/src/db/entities/package_group.rs b/server/src/db/entities/package_group.rs index 59948c3..61e69f2 100644 --- a/server/src/db/entities/package_group.rs +++ b/server/src/db/entities/package_group.rs @@ -9,7 +9,7 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub package_id: i32, #[sea_orm(primary_key, auto_increment = false)] - pub name: String, + pub value: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/server/src/db/entities/package_license.rs b/server/src/db/entities/package_license.rs index c4e0d71..2920d3f 100644 --- a/server/src/db/entities/package_license.rs +++ b/server/src/db/entities/package_license.rs @@ -9,7 +9,7 @@ pub struct Model { #[sea_orm(primary_key, auto_increment = false)] pub package_id: i32, #[sea_orm(primary_key, auto_increment = false)] - pub name: String, + pub value: String, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/server/src/db/entities/package_provides.rs b/server/src/db/entities/package_provides.rs new file mode 100644 index 0000000..7fca6ee --- /dev/null +++ b/server/src/db/entities/package_provides.rs @@ -0,0 +1,33 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 + +use sea_orm::entity::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[sea_orm(table_name = "package_provides")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub package_id: i32, + #[sea_orm(primary_key, auto_increment = false)] + pub value: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::package::Entity", + from = "Column::PackageId", + to = "super::package::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Package, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Package.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/server/src/db/entities/package_replaces.rs b/server/src/db/entities/package_replaces.rs new file mode 100644 index 0000000..0946b2d --- /dev/null +++ b/server/src/db/entities/package_replaces.rs @@ -0,0 +1,33 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1 + +use sea_orm::entity::prelude::*; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] +#[sea_orm(table_name = "package_replaces")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub package_id: i32, + #[sea_orm(primary_key, auto_increment = false)] + pub value: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::package::Entity", + from = "Column::PackageId", + to = "super::package::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Package, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Package.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/server/src/db/entities/prelude.rs b/server/src/db/entities/prelude.rs index 8ebe873..1314174 100644 --- a/server/src/db/entities/prelude.rs +++ b/server/src/db/entities/prelude.rs @@ -2,8 +2,11 @@ pub use super::distro::Entity as Distro; pub use super::package::Entity as Package; +pub use super::package_conflicts::Entity as PackageConflicts; +pub use super::package_depends::Entity as PackageDepends; pub use super::package_file::Entity as PackageFile; pub use super::package_group::Entity as PackageGroup; pub use super::package_license::Entity as PackageLicense; -pub use super::package_related::Entity as PackageRelated; +pub use super::package_provides::Entity as PackageProvides; +pub use super::package_replaces::Entity as PackageReplaces; pub use super::repo::Entity as Repo; diff --git a/server/src/db/entities/repo.rs b/server/src/db/entities/repo.rs index 1ddd39e..d68e226 100644 --- a/server/src/db/entities/repo.rs +++ b/server/src/db/entities/repo.rs @@ -9,6 +9,7 @@ pub struct Model { #[sea_orm(primary_key)] pub id: i32, pub distro_id: i32, + #[sea_orm(unique)] pub name: String, pub description: Option, } diff --git a/server/src/db/migrator/m20230813_000001_create_dist_tables.rs b/server/src/db/migrator/m20230813_000001_create_dist_tables.rs new file mode 100644 index 0000000..46a2842 --- /dev/null +++ b/server/src/db/migrator/m20230813_000001_create_dist_tables.rs @@ -0,0 +1,98 @@ +use sea_orm_migration::prelude::*; + +pub struct Migration; + +impl MigrationName for Migration { + fn name(&self) -> &str { + "m_20230813_000001_create_dist_tables" + } +} + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(Distro::Table) + .col( + ColumnDef::new(Distro::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(Distro::Slug) + .string_len(255) + .not_null() + .unique_key(), + ) + .col( + ColumnDef::new(Distro::Name) + .string() + .not_null() + .unique_key(), + ) + .col(ColumnDef::new(Distro::Description).string()) + .col(ColumnDef::new(Distro::Url).string()) + .to_owned(), + ) + .await?; + manager + .create_table( + Table::create() + .table(Repo::Table) + .col( + ColumnDef::new(Repo::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(Repo::DistroId).integer().not_null()) + .col(ColumnDef::new(Repo::Name).string().not_null().unique_key()) + .col(ColumnDef::new(Repo::Description).string()) + .foreign_key( + ForeignKey::create() + .name("fk-repo-distro_id") + .from(Repo::Table, Repo::DistroId) + .to(Distro::Table, Distro::Id) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + + Ok(()) + } + + // Define how to rollback this migration: Drop the Bakery table. + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table(Table::drop().table(Repo::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(Distro::Table).to_owned()) + .await + } +} + +#[derive(Iden)] +pub enum Distro { + Table, + Id, + Slug, + Name, + Description, + Url, +} + +#[derive(Iden)] +pub enum Repo { + Table, + Id, + DistroId, + Name, + Description, +} diff --git a/server/src/db/migrator/m20230730_000001_create_repo_tables.rs b/server/src/db/migrator/m20230813_000002_create_package_tables.rs similarity index 63% rename from server/src/db/migrator/m20230730_000001_create_repo_tables.rs rename to server/src/db/migrator/m20230813_000002_create_package_tables.rs index f76e639..1cfc208 100644 --- a/server/src/db/migrator/m20230730_000001_create_repo_tables.rs +++ b/server/src/db/migrator/m20230813_000002_create_package_tables.rs @@ -4,58 +4,13 @@ pub struct Migration; impl MigrationName for Migration { fn name(&self) -> &str { - "m_20230730_000001_create_repo_tables" + "m_20230813_000002_create_package_tables" } } #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .create_table( - Table::create() - .table(Distro::Table) - .col( - ColumnDef::new(Distro::Id) - .integer() - .not_null() - .auto_increment() - .primary_key(), - ) - .col( - ColumnDef::new(Distro::Name) - .string() - .not_null() - .unique_key(), - ) - .col(ColumnDef::new(Distro::Description).string()) - .to_owned(), - ) - .await?; - manager - .create_table( - Table::create() - .table(Repo::Table) - .col( - ColumnDef::new(Repo::Id) - .integer() - .not_null() - .auto_increment() - .primary_key(), - ) - .col(ColumnDef::new(Repo::DistroId).integer().not_null()) - .col(ColumnDef::new(Repo::Name).string().not_null().unique_key()) - .col(ColumnDef::new(Repo::Description).string()) - .foreign_key( - ForeignKey::create() - .name("fk-repo-distro_id") - .from(Repo::Table, Repo::DistroId) - .to(Distro::Table, Distro::Id) - .on_delete(ForeignKeyAction::Cascade), - ) - .to_owned(), - ) - .await?; manager .create_table( Table::create() @@ -81,12 +36,6 @@ impl MigrationTrait for Migration { .col(ColumnDef::new(Package::PgpSig).string_len(255)) .col(ColumnDef::new(Package::PgpSigSize).big_integer()) .col(ColumnDef::new(Package::Sha256Sum).char_len(64).not_null()) - .col( - ColumnDef::new(Package::Compression) - .string_len(16) - .not_null(), - ) - .col(ColumnDef::new(Package::State).integer().not_null()) .foreign_key( ForeignKey::create() .name("fk-package-repo_id") @@ -107,14 +56,14 @@ impl MigrationTrait for Migration { .not_null(), ) .col( - ColumnDef::new(PackageLicense::Name) + ColumnDef::new(PackageLicense::Value) .string_len(255) .not_null(), ) .primary_key( Index::create() .col(PackageLicense::PackageId) - .col(PackageLicense::Name), + .col(PackageLicense::Value), ) .foreign_key( ForeignKey::create() @@ -132,14 +81,14 @@ impl MigrationTrait for Migration { .table(PackageGroup::Table) .col(ColumnDef::new(PackageGroup::PackageId).integer().not_null()) .col( - ColumnDef::new(PackageGroup::Name) + ColumnDef::new(PackageGroup::Value) .string_len(255) .not_null(), ) .primary_key( Index::create() .col(PackageGroup::PackageId) - .col(PackageGroup::Name), + .col(PackageGroup::Value), ) .foreign_key( ForeignKey::create() @@ -154,28 +103,119 @@ impl MigrationTrait for Migration { manager .create_table( Table::create() - .table(PackageRelated::Table) + .table(PackageReplaces::Table) .col( - ColumnDef::new(PackageRelated::PackageId) + ColumnDef::new(PackageReplaces::PackageId) .integer() .not_null(), ) - .col(ColumnDef::new(PackageRelated::Type).integer().not_null()) .col( - ColumnDef::new(PackageRelated::Name) + ColumnDef::new(PackageReplaces::Value) .string_len(255) .not_null(), ) .primary_key( Index::create() - .col(PackageRelated::PackageId) - .col(PackageRelated::Type) - .col(PackageRelated::Name), + .col(PackageReplaces::PackageId) + .col(PackageReplaces::Value), + ) + .foreign_key( + ForeignKey::create() + .name("fk-package_replaces-package_id") + .from(PackageReplaces::Table, PackageReplaces::PackageId) + .to(Package::Table, Package::Id) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + manager + .create_table( + Table::create() + .table(PackageConflicts::Table) + .col( + ColumnDef::new(PackageConflicts::PackageId) + .integer() + .not_null(), + ) + .col( + ColumnDef::new(PackageConflicts::Value) + .string_len(255) + .not_null(), + ) + .primary_key( + Index::create() + .col(PackageConflicts::PackageId) + .col(PackageConflicts::Value), + ) + .foreign_key( + ForeignKey::create() + .name("fk-package_conflicts-package_id") + .from(PackageConflicts::Table, PackageConflicts::PackageId) + .to(Package::Table, Package::Id) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + manager + .create_table( + Table::create() + .table(PackageProvides::Table) + .col( + ColumnDef::new(PackageProvides::PackageId) + .integer() + .not_null(), + ) + .col( + ColumnDef::new(PackageProvides::Value) + .string_len(255) + .not_null(), + ) + .primary_key( + Index::create() + .col(PackageProvides::PackageId) + .col(PackageProvides::Value), + ) + .foreign_key( + ForeignKey::create() + .name("fk-package_provides-package_id") + .from(PackageProvides::Table, PackageProvides::PackageId) + .to(Package::Table, Package::Id) + .on_delete(ForeignKeyAction::Cascade), + ) + .to_owned(), + ) + .await?; + manager + .create_table( + Table::create() + .table(PackageDepends::Table) + .col( + ColumnDef::new(PackageDepends::PackageId) + .integer() + .not_null(), + ) + .col( + ColumnDef::new(PackageDepends::Type) + .string_len(6) + .not_null(), + ) + .col( + ColumnDef::new(PackageDepends::Value) + .string_len(255) + .not_null(), + ) + .primary_key( + Index::create() + .col(PackageDepends::PackageId) + .col(PackageDepends::Type) + .col(PackageDepends::Value), ) .foreign_key( ForeignKey::create() .name("fk-package_depends-package_id") - .from(PackageRelated::Table, PackageRelated::PackageId) + .from(PackageDepends::Table, PackageDepends::PackageId) .to(Package::Table, Package::Id) .on_delete(ForeignKeyAction::Cascade), ) @@ -187,11 +227,15 @@ impl MigrationTrait for Migration { Table::create() .table(PackageFile::Table) .col(ColumnDef::new(PackageFile::PackageId).integer().not_null()) - .col(ColumnDef::new(PackageFile::Path).string_len(255).not_null()) + .col( + ColumnDef::new(PackageFile::Value) + .string_len(255) + .not_null(), + ) .primary_key( Index::create() .col(PackageFile::PackageId) - .col(PackageFile::Path), + .col(PackageFile::Value), ) .foreign_key( ForeignKey::create() @@ -216,38 +260,30 @@ impl MigrationTrait for Migration { .drop_table(Table::drop().table(PackageGroup::Table).to_owned()) .await?; manager - .drop_table(Table::drop().table(PackageRelated::Table).to_owned()) + .drop_table(Table::drop().table(PackageReplaces::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(PackageConflicts::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(PackageProvides::Table).to_owned()) + .await?; + manager + .drop_table(Table::drop().table(PackageDepends::Table).to_owned()) .await?; manager .drop_table(Table::drop().table(PackageFile::Table).to_owned()) .await?; manager .drop_table(Table::drop().table(Package::Table).to_owned()) - .await?; - manager - .drop_table(Table::drop().table(Repo::Table).to_owned()) - .await?; - manager - .drop_table(Table::drop().table(Distro::Table).to_owned()) .await } } -#[derive(Iden)] -pub enum Distro { - Table, - Id, - Name, - Description, -} - #[derive(Iden)] pub enum Repo { Table, Id, - DistroId, - Name, - Description, } #[derive(Iden)] @@ -268,35 +304,54 @@ pub enum Package { PgpSig, PgpSigSize, Sha256Sum, - Compression, - State, } #[derive(Iden)] pub enum PackageLicense { Table, PackageId, - Name, + Value, } #[derive(Iden)] pub enum PackageGroup { Table, PackageId, - Name, + Value, } #[derive(Iden)] -pub enum PackageRelated { +pub enum PackageReplaces { + Table, + PackageId, + Value, +} + +#[derive(Iden)] +pub enum PackageConflicts { + Table, + PackageId, + Value, +} + +#[derive(Iden)] +pub enum PackageProvides { + Table, + PackageId, + Value, +} + +#[derive(Iden)] +pub enum PackageDepends { Table, PackageId, Type, - Name, + Value, } #[derive(Iden)] pub enum PackageFile { Table, PackageId, - Path, + Value, } diff --git a/server/src/db/migrator/mod.rs b/server/src/db/migrator/mod.rs index d939276..0d8899b 100644 --- a/server/src/db/migrator/mod.rs +++ b/server/src/db/migrator/mod.rs @@ -1,12 +1,16 @@ +mod m20230813_000001_create_dist_tables; +mod m20230813_000002_create_package_tables; + use sea_orm_migration::prelude::*; pub struct Migrator; -mod m20230730_000001_create_repo_tables; - #[async_trait::async_trait] impl MigratorTrait for Migrator { fn migrations() -> Vec> { - vec![Box::new(m20230730_000001_create_repo_tables::Migration)] + vec![ + Box::new(m20230813_000001_create_dist_tables::Migration), + Box::new(m20230813_000002_create_package_tables::Migration), + ] } } diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs index 2b03fb1..32c0452 100644 --- a/server/src/db/mod.rs +++ b/server/src/db/mod.rs @@ -1,46 +1,28 @@ +mod conn; pub mod entities; mod migrator; -pub mod query; +mod query; -use crate::config::DbConfig; +use sea_orm::{ConnectOptions, Database, DatabaseConnection, DeriveActiveEnum, EnumIter}; +use sea_orm_migration::MigratorTrait; +use serde::{Deserialize, Serialize}; pub use entities::{prelude::*, *}; -pub use migrator::Migrator; - -use sea_orm::{ConnectionTrait, Database, DbConn, DeriveActiveEnum, EnumIter}; -use serde::{Deserialize, Serialize}; +use migrator::Migrator; type Result = std::result::Result; #[derive(EnumIter, DeriveActiveEnum, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] -#[sea_orm(rs_type = "i32", db_type = "Integer")] -#[serde(rename_all = "lowercase")] -pub enum PackageRelatedEnum { - #[sea_orm(num_value = 0)] - Conflicts, - #[sea_orm(num_value = 1)] - Replaces, - #[sea_orm(num_value = 2)] - Provides, - #[sea_orm(num_value = 3)] +#[sea_orm(rs_type = "String", db_type = "String(Some(6))")] +pub enum PackageDepend { + #[sea_orm(string_value = "depend")] Depend, - #[sea_orm(num_value = 4)] - Makedepend, - #[sea_orm(num_value = 5)] - Checkdepend, - #[sea_orm(num_value = 6)] - Optdepend, -} - -#[derive(EnumIter, DeriveActiveEnum, Deserialize, Serialize, PartialEq, Eq, Clone, Debug)] -#[sea_orm(rs_type = "i32", db_type = "Integer")] -pub enum PackageState { - #[sea_orm(num_value = 0)] - PendingCommit, - #[sea_orm(num_value = 1)] - Committed, - #[sea_orm(num_value = 2)] - PendingDeletion, + #[sea_orm(string_value = "make")] + Make, + #[sea_orm(string_value = "check")] + Check, + #[sea_orm(string_value = "opt")] + Opt, } #[derive(Serialize)] @@ -49,53 +31,31 @@ pub struct FullPackage { entry: package::Model, licenses: Vec, groups: Vec, - related: Vec<(PackageRelatedEnum, String)>, + replaces: Vec, + provides: Vec, + depends: Vec<(PackageDepend, String)>, files: Vec, } -pub async fn connect(conn: &DbConfig) -> crate::Result { - match conn { - DbConfig::Sqlite { - db_dir, - max_connections, - } => { - let url = format!( - "sqlite://{}?mode=rwc", - db_dir.join("rieter.sqlite").to_string_lossy() - ); - let options = sea_orm::ConnectOptions::new(url) - .max_connections(*max_connections) - .to_owned(); +#[derive(Clone, Debug)] +pub struct RieterDb { + conn: DatabaseConnection, + pub pkg: query::PackageQuery, + pub repo: query::RepoQuery, + pub distro: query::DistroQuery, +} - let conn = Database::connect(options).await?; +impl RieterDb { + pub async fn connect>(opt: C) -> Result { + let db = Database::connect(opt).await?; - // synchronous=NORMAL still ensures database consistency with WAL mode, as per the docs - // https://www.sqlite.org/pragma.html#pragma_synchronous - conn.execute_unprepared("PRAGMA journal_mode=WAL;").await?; - conn.execute_unprepared("PRAGMA synchronous=NORMAL;") - .await?; + Migrator::up(&db, None).await?; - Ok(conn) - } - DbConfig::Postgres { - host, - port, - db, - user, - password, - schema, - max_connections, - } => { - let mut url = format!("postgres://{}:{}@{}:{}/{}", user, password, host, port, db); - - if !schema.is_empty() { - url = format!("{url}?currentSchema={schema}"); - } - - let options = sea_orm::ConnectOptions::new(url) - .max_connections(*max_connections) - .to_owned(); - Ok(Database::connect(options).await?) - } + Ok(Self { + conn: db.clone(), + pkg: query::PackageQuery::new(db.clone()), + repo: query::RepoQuery::new(db.clone()), + distro: query::DistroQuery::new(db.clone()), + }) } } diff --git a/server/src/db/query/distro.rs b/server/src/db/query/distro.rs index 8647f2a..1913f99 100644 --- a/server/src/db/query/distro.rs +++ b/server/src/db/query/distro.rs @@ -1,46 +1,52 @@ +use sea_orm::*; + use crate::db::*; -use sea_orm::{sea_query::IntoCondition, *}; - -#[derive(Deserialize)] -pub struct Filter { - name: Option, +#[derive(Clone, Debug)] +pub struct DistroQuery { + conn: DatabaseConnection, } -impl IntoCondition for Filter { - fn into_condition(self) -> Condition { - Condition::all().add_option( - self.name - .map(|name| distro::Column::Name.like(format!("%{}%", name))), - ) +impl DistroQuery { + pub fn new(conn: DatabaseConnection) -> Self { + Self { conn } + } + + pub async fn page(&self, per_page: u64, page: u64) -> Result<(u64, Vec)> { + let paginator = Distro::find() + .order_by_asc(distro::Column::Id) + .paginate(&self.conn, per_page); + let results = paginator.fetch_page(page).await?; + let total_pages = paginator.num_pages().await?; + + Ok((total_pages, results)) + } + + pub async fn by_id(&self, id: i32) -> Result> { + distro::Entity::find_by_id(id).one(&self.conn).await + } + + pub async fn insert( + &self, + slug: &str, + name: &str, + description: Option<&str>, + url: Option<&str>, + ) -> Result> { + let model = distro::ActiveModel { + id: NotSet, + slug: Set(String::from(slug)), + name: Set(String::from(name)), + description: Set(description.map(String::from)), + url: Set(url.map(String::from)), + }; + + Distro::insert(model).exec(&self.conn).await + } + + pub async fn insert_model(&self, model: distro::Model) -> Result { + let mut model: distro::ActiveModel = model.into(); + model.id = NotSet; + model.insert(&self.conn).await } } - -pub async fn page( - conn: &DbConn, - per_page: u64, - page: u64, - filter: Filter, -) -> Result> { - let paginator = Distro::find() - .filter(filter) - .order_by_asc(distro::Column::Id) - .paginate(conn, per_page); - let repos = paginator.fetch_page(page).await?; - - Ok(repos) -} - -pub async fn by_id(conn: &DbConn, id: i32) -> Result> { - distro::Entity::find_by_id(id).one(conn).await -} - -pub async fn insert(conn: &DbConn, name: &str, description: Option<&str>) -> Result { - let model = distro::ActiveModel { - id: NotSet, - name: Set(String::from(name)), - description: Set(description.map(String::from)), - }; - - model.insert(conn).await -} diff --git a/server/src/db/query/mod.rs b/server/src/db/query/mod.rs index 9eb7954..4ffa4cb 100644 --- a/server/src/db/query/mod.rs +++ b/server/src/db/query/mod.rs @@ -1,3 +1,9 @@ -pub mod distro; -pub mod package; -pub mod repo; +mod distro; +mod package; +mod repo; + +pub use distro::DistroQuery; +pub use package::PackageQuery; +pub use repo::RepoQuery; + +type Result = std::result::Result; diff --git a/server/src/db/query/package.rs b/server/src/db/query/package.rs index 8a4f054..eed5ead 100644 --- a/server/src/db/query/package.rs +++ b/server/src/db/query/package.rs @@ -1,376 +1,213 @@ -use crate::db::{self, *}; +use sea_orm::*; -use sea_orm::{sea_query::IntoCondition, *}; -use sea_query::{Alias, Expr, Query, SelectStatement}; -use serde::Deserialize; +use crate::db::*; -/// How many fields may be inserted at once into the database. -const PACKAGE_INSERT_LIMIT: usize = 1000; - -#[derive(Deserialize)] -pub struct Filter { - repo: Option, - arch: Option, - name: Option, +#[derive(Clone, Debug)] +pub struct PackageQuery { + conn: DatabaseConnection, } -impl IntoCondition for Filter { - fn into_condition(self) -> Condition { - Condition::all() - .add_option(self.repo.map(|repo| package::Column::RepoId.eq(repo))) - .add_option(self.arch.map(|arch| package::Column::Arch.eq(arch))) - .add_option(self.name.map(|name| package::Column::Name.contains(name))) - } -} - -pub async fn page( - conn: &DbConn, - per_page: u64, - page: u64, - filter: Filter, -) -> crate::Result> { - let p2 = Alias::new("p2"); - let query = Query::select() - .columns(db::package::Column::iter().map(|c| (db::package::Entity, c))) - .from(db::package::Entity) - .join_subquery( - JoinType::InnerJoin, - max_pkg_ids_query(true), - p2.clone(), - Expr::col((db::package::Entity, db::package::Column::Id)) - .eq(Expr::col((p2.clone(), Alias::new("max_id")))), - ) - .cond_where(filter) - .order_by((db::package::Entity, db::package::Column::Id), Order::Asc) - .to_owned(); - let builder = conn.get_database_backend(); - let sql = builder.build(&query); - - Ok(db::Package::find() - .from_raw_sql(sql) - .paginate(conn, per_page) - .fetch_page(page) - .await?) -} - -pub async fn by_id(conn: &DbConn, id: i32) -> Result> { - package::Entity::find_by_id(id).one(conn).await -} - -pub async fn by_fields( - conn: &DbConn, - repo_id: i32, - name: &str, - version: &str, - arch: &str, - compression: &str, -) -> Result> { - let cond = Condition::all() - .add(package::Column::RepoId.eq(repo_id)) - .add(package::Column::Name.eq(name)) - .add(package::Column::Arch.eq(arch)) - .add(package::Column::Version.eq(version)) - .add(package::Column::Compression.eq(compression)); - - Package::find().filter(cond).one(conn).await -} - -pub async fn delete_with_arch(conn: &DbConn, repo_id: i32, arch: &str) -> Result { - Package::delete_many() - .filter(package::Column::RepoId.eq(repo_id)) - .filter(package::Column::Arch.eq(arch)) - .exec(conn) - .await -} - -pub async fn insert( - conn: &DbConn, - repo_id: i32, - pkg: crate::repo::package::Package, -) -> Result { - let info = pkg.info; - - // Doing this manually is not the recommended way, but the generic error type of the - // transaction function didn't play well with my current error handling - let txn = conn.begin().await?; - - let model = package::ActiveModel { - id: NotSet, - repo_id: Set(repo_id), - base: Set(info.base), - name: Set(info.name), - version: Set(info.version), - arch: Set(info.arch), - size: Set(info.size), - c_size: Set(info.csize), - description: Set(info.description), - url: Set(info.url), - build_date: Set(info.build_date), - packager: Set(info.packager), - pgp_sig: Set(info.pgpsig), - pgp_sig_size: Set(info.pgpsigsize), - sha256_sum: Set(info.sha256sum), - compression: Set(pkg.compression.extension().unwrap().to_string()), - state: Set(PackageState::PendingCommit), - }; - - let pkg_entry = model.insert(&txn).await?; - - // Insert all the related tables - PackageLicense::insert_many(info.licenses.iter().map(|s| package_license::ActiveModel { - package_id: Set(pkg_entry.id), - name: Set(s.to_string()), - })) - .on_empty_do_nothing() - .exec(&txn) - .await?; - - PackageGroup::insert_many(info.groups.iter().map(|s| package_group::ActiveModel { - package_id: Set(pkg_entry.id), - name: Set(s.to_string()), - })) - .on_empty_do_nothing() - .exec(&txn) - .await?; - - let related = info - .conflicts - .iter() - .map(|s| (PackageRelatedEnum::Conflicts, s)) - .chain( - info.replaces - .iter() - .map(|s| (PackageRelatedEnum::Replaces, s)), - ) - .chain( - info.provides - .iter() - .map(|s| (PackageRelatedEnum::Provides, s)), - ) - .chain(info.depends.iter().map(|s| (PackageRelatedEnum::Depend, s))) - .chain( - info.makedepends - .iter() - .map(|s| (PackageRelatedEnum::Makedepend, s)), - ) - .chain( - info.checkdepends - .iter() - .map(|s| (PackageRelatedEnum::Checkdepend, s)), - ) - .chain( - info.optdepends - .iter() - .map(|s| (PackageRelatedEnum::Optdepend, s)), - ); - let related = crate::util::Chunked::new(related, PACKAGE_INSERT_LIMIT); - - for chunk in related { - PackageRelated::insert_many( - chunk - .into_iter() - .map(|(t, s)| package_related::ActiveModel { - package_id: Set(pkg_entry.id), - r#type: Set(t), - name: Set(s.to_string()), - }), - ) - .on_empty_do_nothing() - .exec(&txn) - .await?; +impl PackageQuery { + pub fn new(conn: DatabaseConnection) -> Self { + Self { conn } } - let files = crate::util::Chunked::new(pkg.files, PACKAGE_INSERT_LIMIT); + pub async fn page( + &self, + per_page: u64, + page: u64, + ) -> super::Result<(u64, Vec)> { + let paginator = Package::find() + .order_by_asc(package::Column::Id) + .paginate(&self.conn, per_page); + let packages = paginator.fetch_page(page).await?; + let total_pages = paginator.num_pages().await?; - for chunk in files { - PackageFile::insert_many(chunk.into_iter().map(|s| package_file::ActiveModel { + Ok((total_pages, packages)) + } + + pub async fn by_id(&self, id: i32) -> Result> { + package::Entity::find_by_id(id).one(&self.conn).await + } + + pub async fn by_fields( + &self, + repo_id: i32, + name: &str, + version: Option<&str>, + arch: &str, + ) -> Result> { + let mut query = Package::find() + .filter(package::Column::RepoId.eq(repo_id)) + .filter(package::Column::Name.eq(name)) + .filter(package::Column::Arch.eq(arch)); + + if let Some(version) = version { + query = query.filter(package::Column::Version.eq(version)); + } + + query.one(&self.conn).await + } + + pub async fn delete_with_arch(&self, repo_id: i32, arch: &str) -> Result { + Package::delete_many() + .filter(package::Column::RepoId.eq(repo_id)) + .filter(package::Column::Arch.eq(arch)) + .exec(&self.conn) + .await + } + + pub async fn insert(&self, repo_id: i32, pkg: crate::repo::package::Package) -> Result<()> { + let info = pkg.info; + + let model = package::ActiveModel { + id: NotSet, + repo_id: Set(repo_id), + base: Set(info.base), + name: Set(info.name), + version: Set(info.version), + arch: Set(info.arch), + size: Set(info.size), + c_size: Set(info.csize), + description: Set(info.description), + url: Set(info.url), + build_date: Set(info.build_date), + packager: Set(info.packager), + pgp_sig: Set(info.pgpsig), + pgp_sig_size: Set(info.pgpsigsize), + sha256_sum: Set(info.sha256sum), + }; + + let pkg_entry = model.insert(&self.conn).await?; + + // Insert all the related tables + PackageLicense::insert_many(info.licenses.iter().map(|s| package_license::ActiveModel { package_id: Set(pkg_entry.id), - path: Set(s.display().to_string()), + value: Set(s.to_string()), })) .on_empty_do_nothing() - .exec(&txn) + .exec(&self.conn) .await?; - } - txn.commit().await?; - - Ok(pkg_entry) -} - -pub async fn full(conn: &DbConn, id: i32) -> Result> { - if let Some(entry) = by_id(conn, id).await? { - let licenses: Vec = entry - .find_related(PackageLicense) - .select_only() - .column(package_license::Column::Name) - .into_tuple() - .all(conn) - .await?; - let groups: Vec = entry - .find_related(PackageGroup) - .select_only() - .column(package_group::Column::Name) - .into_tuple() - .all(conn) - .await?; - let related: Vec<(db::PackageRelatedEnum, String)> = entry - .find_related(PackageRelated) - .select_only() - .columns([package_related::Column::Type, package_related::Column::Name]) - .into_tuple() - .all(conn) - .await?; - let files: Vec = entry - .find_related(PackageFile) - .select_only() - .column(package_file::Column::Path) - .into_tuple() - .all(conn) - .await?; - - Ok(Some(FullPackage { - entry, - licenses, - groups, - related, - files, + PackageGroup::insert_many(info.groups.iter().map(|s| package_group::ActiveModel { + package_id: Set(pkg_entry.id), + value: Set(s.to_string()), })) - } else { - Ok(None) - } -} + .on_empty_do_nothing() + .exec(&self.conn) + .await?; -#[derive(FromQueryResult)] -pub struct PkgToRemove { - pub repo_id: i32, - pub id: i32, -} + PackageReplaces::insert_many(info.replaces.iter().map(|s| package_replaces::ActiveModel { + package_id: Set(pkg_entry.id), + value: Set(s.to_string()), + })) + .on_empty_do_nothing() + .exec(&self.conn) + .await?; -fn max_pkg_ids_query(committed: bool) -> SelectStatement { - let mut query = Query::select() - .from(db::package::Entity) - .columns([ - db::package::Column::RepoId, - db::package::Column::Arch, - db::package::Column::Name, - ]) - .expr_as(db::package::Column::Id.max(), Alias::new("max_id")) - .group_by_columns([ - db::package::Column::RepoId, - db::package::Column::Arch, - db::package::Column::Name, - ]) - .to_owned(); + PackageConflicts::insert_many(info.conflicts.iter().map(|s| { + package_conflicts::ActiveModel { + package_id: Set(pkg_entry.id), + value: Set(s.to_string()), + } + })) + .on_empty_do_nothing() + .exec(&self.conn) + .await?; - if committed { - query.cond_where(db::package::Column::State.eq(db::PackageState::Committed)); + PackageProvides::insert_many(info.provides.iter().map(|s| package_provides::ActiveModel { + package_id: Set(pkg_entry.id), + value: Set(s.to_string()), + })) + .on_empty_do_nothing() + .exec(&self.conn) + .await?; + + PackageFile::insert_many(pkg.files.iter().map(|s| package_file::ActiveModel { + package_id: Set(pkg_entry.id), + value: Set(s.display().to_string()), + })) + .on_empty_do_nothing() + .exec(&self.conn) + .await?; + + let deps = info + .depends + .iter() + .map(|d| (PackageDepend::Depend, d)) + .chain(info.makedepends.iter().map(|d| (PackageDepend::Make, d))) + .chain(info.checkdepends.iter().map(|d| (PackageDepend::Check, d))) + .chain(info.optdepends.iter().map(|d| (PackageDepend::Opt, d))) + .map(|(t, s)| package_depends::ActiveModel { + package_id: Set(pkg_entry.id), + r#type: Set(t), + value: Set(s.to_string()), + }); + + PackageDepends::insert_many(deps) + .on_empty_do_nothing() + .exec(&self.conn) + .await?; + + Ok(()) } - query -} + pub async fn full(&self, id: i32) -> Result> { + if let Some(entry) = self.by_id(id).await? { + let licenses = entry + .find_related(PackageLicense) + .all(&self.conn) + .await? + .into_iter() + .map(|e| e.value) + .collect(); + let groups = entry + .find_related(PackageGroup) + .all(&self.conn) + .await? + .into_iter() + .map(|e| e.value) + .collect(); + let replaces = entry + .find_related(PackageReplaces) + .all(&self.conn) + .await? + .into_iter() + .map(|e| e.value) + .collect(); + let provides = entry + .find_related(PackageProvides) + .all(&self.conn) + .await? + .into_iter() + .map(|e| e.value) + .collect(); + let depends = entry + .find_related(PackageDepends) + .all(&self.conn) + .await? + .into_iter() + .map(|e| (e.r#type, e.value)) + .collect(); + let files = entry + .find_related(PackageFile) + .all(&self.conn) + .await? + .into_iter() + .map(|e| e.value) + .collect(); -/// Query that returns all packages that should be included in a sync for the given repository and -/// arch. -pub fn pkgs_to_sync( - conn: &DbConn, - repo: i32, - arch: &str, -) -> SelectorRaw> { - let (p1, p2) = (Alias::new("p1"), Alias::new("p2")); - let query = Query::select() - .columns(db::package::Column::iter().map(|c| (p1.clone(), c))) - .from_as(db::package::Entity, p1.clone()) - .join_subquery( - JoinType::InnerJoin, - max_pkg_ids_query(false), - p2.clone(), - Expr::col((p1.clone(), db::package::Column::Id)) - .eq(Expr::col((p2.clone(), Alias::new("max_id")))), - ) - .cond_where( - Condition::all() - .add(Expr::col((p1.clone(), db::package::Column::RepoId)).eq(repo)) - .add( - Expr::col((p1.clone(), db::package::Column::Arch)) - .is_in([arch, crate::ANY_ARCH]), - ) - .add( - Expr::col((p1.clone(), db::package::Column::State)) - .ne(db::PackageState::PendingDeletion), - ), - ) - .to_owned(); - let builder = conn.get_database_backend(); - let sql = builder.build(&query); - - db::Package::find().from_raw_sql(sql) -} - -fn stale_pkgs_query(include_repo: bool) -> SelectStatement { - let (p1, p2) = (Alias::new("p1"), Alias::new("p2")); - let mut query = Query::select() - .from_as(db::package::Entity, p1.clone()) - .to_owned(); - - if include_repo { - query.columns([ - (p1.clone(), db::package::Column::RepoId), - (p1.clone(), db::package::Column::Id), - ]); - } else { - query.column((p1.clone(), db::package::Column::Id)); + Ok(Some(FullPackage { + entry, + licenses, + groups, + replaces, + provides, + depends, + files, + })) + } else { + Ok(None) + } } - - // We left join on the max pkgs query because a repository that has all its packages set to - // "pending deletion" doesn't show up in the query. These are also included with a where clause - // on the joined rows. - query - .join_subquery( - JoinType::LeftJoin, - max_pkg_ids_query(true), - p2.clone(), - Condition::all() - .add( - Expr::col((p1.clone(), db::package::Column::RepoId)) - .eq(Expr::col((p2.clone(), db::package::Column::RepoId))), - ) - .add( - Expr::col((p1.clone(), db::package::Column::Arch)) - .eq(Expr::col((p2.clone(), db::package::Column::Arch))), - ) - .add( - Expr::col((p1.clone(), db::package::Column::Name)) - .eq(Expr::col((p2.clone(), db::package::Column::Name))), - ), - ) - .cond_where( - Condition::any() - .add( - Expr::col((p1.clone(), db::package::Column::Id)) - .lt(Expr::col((p2.clone(), Alias::new("max_id")))), - ) - .add( - Expr::col((p1.clone(), db::package::Column::State)) - .eq(db::PackageState::PendingDeletion), - ), - ); - - query -} - -pub fn stale_pkgs(conn: &DbConn) -> SelectorRaw> { - let query = stale_pkgs_query(true); - let builder = conn.get_database_backend(); - let sql = builder.build(&query); - - PkgToRemove::find_by_statement(sql) -} - -pub async fn delete_stale_pkgs(conn: &DbConn, max_id: i32) -> crate::Result<()> { - Ok(db::Package::delete_many() - .filter(db::package::Column::Id.lte(max_id)) - .filter(db::package::Column::Id.in_subquery(stale_pkgs_query(false))) - .exec(conn) - .await - .map(|_| ())?) } diff --git a/server/src/db/query/repo.rs b/server/src/db/query/repo.rs index a2daa26..8b30db8 100644 --- a/server/src/db/query/repo.rs +++ b/server/src/db/query/repo.rs @@ -1,59 +1,51 @@ +use sea_orm::*; + use crate::db::*; -use sea_orm::{sea_query::IntoCondition, *}; - -#[derive(Deserialize)] -pub struct Filter { - name: Option, +#[derive(Clone, Debug)] +pub struct RepoQuery { + conn: DatabaseConnection, } -impl IntoCondition for Filter { - fn into_condition(self) -> Condition { - Condition::all().add_option( - self.name - .map(|name| repo::Column::Name.like(format!("%{}%", name))), - ) +impl RepoQuery { + pub fn new(conn: DatabaseConnection) -> Self { + Self { conn } + } + + pub async fn page(&self, per_page: u64, page: u64) -> Result<(u64, Vec)> { + let paginator = Repo::find() + .order_by_asc(repo::Column::Id) + .paginate(&self.conn, per_page); + let repos = paginator.fetch_page(page).await?; + let total_pages = paginator.num_pages().await?; + + Ok((total_pages, repos)) + } + + pub async fn by_id(&self, id: i32) -> Result> { + repo::Entity::find_by_id(id).one(&self.conn).await + } + + pub async fn by_name(&self, name: &str) -> Result> { + Repo::find() + .filter(repo::Column::Name.eq(name)) + .one(&self.conn) + .await + } + + pub async fn insert( + &self, + name: &str, + description: Option<&str>, + ) -> Result> { + let model = repo::ActiveModel { + id: NotSet, + // TODO CHANGE THIS + distro_id: NotSet, + name: Set(String::from(name)), + description: Set(description.map(String::from)), + }; + + Repo::insert(model).exec(&self.conn).await } } - -pub async fn page( - conn: &DbConn, - per_page: u64, - page: u64, - filter: Filter, -) -> Result> { - let paginator = Repo::find() - .filter(filter) - .order_by_asc(repo::Column::Id) - .paginate(conn, per_page); - let repos = paginator.fetch_page(page).await?; - - Ok(repos) -} - -pub async fn by_id(conn: &DbConn, id: i32) -> Result> { - repo::Entity::find_by_id(id).one(conn).await -} - -pub async fn by_name(conn: &DbConn, name: &str) -> Result> { - Repo::find() - .filter(repo::Column::Name.eq(name)) - .one(conn) - .await -} - -pub async fn insert( - conn: &DbConn, - distro_id: i32, - name: &str, - description: Option<&str>, -) -> Result { - let model = repo::ActiveModel { - id: NotSet, - distro_id: Set(distro_id), - name: Set(String::from(name)), - description: Set(description.map(String::from)), - }; - - model.insert(conn).await -} diff --git a/server/src/error.rs b/server/src/error.rs index e0626d4..723e944 100644 --- a/server/src/error.rs +++ b/server/src/error.rs @@ -1,9 +1,8 @@ -use std::{error::Error, fmt, io}; - -use axum::{ - http::StatusCode, - response::{IntoResponse, Response}, -}; +use axum::http::StatusCode; +use axum::response::{IntoResponse, Response}; +use std::error::Error; +use std::fmt; +use std::io; pub type Result = std::result::Result; @@ -13,9 +12,6 @@ pub enum ServerError { Axum(axum::Error), Db(sea_orm::DbErr), Status(StatusCode), - Archive(libarchive::error::ArchiveError), - Figment(figment::Error), - Unit, } impl fmt::Display for ServerError { @@ -25,9 +21,6 @@ impl fmt::Display for ServerError { ServerError::Axum(err) => write!(fmt, "{}", err), ServerError::Status(status) => write!(fmt, "{}", status), ServerError::Db(err) => write!(fmt, "{}", err), - ServerError::Archive(err) => write!(fmt, "{}", err), - ServerError::Figment(err) => write!(fmt, "{}", err), - ServerError::Unit => Ok(()), } } } @@ -42,13 +35,12 @@ impl IntoResponse for ServerError { ServerError::IO(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), ServerError::Axum(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), ServerError::Status(status) => status.into_response(), - ServerError::Db(sea_orm::DbErr::RecordNotFound(_)) => { - StatusCode::NOT_FOUND.into_response() + ServerError::Db(err) => match err { + sea_orm::DbErr::RecordNotFound(_) => StatusCode::NOT_FOUND, + sea_orm::DbErr::Query(_) => StatusCode::BAD_REQUEST, + _ => StatusCode::INTERNAL_SERVER_ERROR, } - ServerError::Db(_) - | ServerError::Archive(_) - | ServerError::Figment(_) - | ServerError::Unit => StatusCode::INTERNAL_SERVER_ERROR.into_response(), + .into_response(), } } } @@ -82,15 +74,3 @@ impl From for ServerError { ServerError::Db(err) } } - -impl From for ServerError { - fn from(err: libarchive::error::ArchiveError) -> Self { - ServerError::Archive(err) - } -} - -impl From for ServerError { - fn from(err: figment::Error) -> Self { - ServerError::Figment(err) - } -} diff --git a/server/src/main.rs b/server/src/main.rs index 7118da5..1d90a24 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,100 +1,32 @@ mod cli; -mod config; pub mod db; mod error; mod repo; -mod util; mod web; -pub use config::{Config, DbConfig, FsConfig}; -pub use error::{Result, ServerError}; - -use std::{io, path::PathBuf}; - use clap::Parser; -use sea_orm_migration::MigratorTrait; -use tokio::runtime; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; +pub use error::{Result, ServerError}; +use repo::RepoGroupManager; +use std::path::PathBuf; +use std::sync::{Arc, RwLock}; -pub const ANY_ARCH: &str = "any"; -pub const PKG_FILENAME_REGEX: &str = "^([a-z0-9@._+-]+)-((?:[0-9]+:)?[a-zA-Z0-9@._+]+-[0-9]+)-([a-zA-z0-9_]+).pkg.tar.([a-zA-Z0-9]+)$"; +#[derive(Clone)] +pub struct Config { + data_dir: PathBuf, + repo_dir: PathBuf, + pkg_dir: PathBuf, + api_key: String, +} #[derive(Clone)] pub struct Global { - config: crate::config::Config, - repo: repo::Handle, - db: sea_orm::DbConn, - pkg_filename_re: regex::Regex, + config: Config, + repo_manager: Arc>, + db: db::RieterDb, } -fn main() -> crate::Result<()> { - let rt = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap(); - let handle = rt.handle(); - +#[tokio::main] +async fn main() -> crate::Result<()> { let cli = cli::Cli::parse(); - let global = setup(handle, cli.config_file)?; - - handle.block_on(run(global)) -} - -fn setup(rt: &runtime::Handle, config_file: PathBuf) -> crate::Result { - let config: Config = Config::figment(config_file) - .extract() - .inspect_err(|e| tracing::error!("{}", e))?; - - tracing_subscriber::registry() - .with(tracing_subscriber::EnvFilter::new(config.log_level.clone())) - .with(tracing_subscriber::fmt::layer()) - .init(); - - tracing::info!("Connecting to database"); - let db = rt.block_on(crate::db::connect(&config.db))?; - rt.block_on(crate::db::Migrator::up(&db, None))?; - - let repo = match &config.fs { - FsConfig::Local { data_dir } => { - crate::repo::start( - data_dir.join("repos"), - db.clone(), - rt.clone(), - config.pkg_workers, - )? - //rt.block_on(crate::repo::RepoMgr::new( - // data_dir.join("repos"), - // db.clone(), - //))? - //RepoHandle::start(data_dir.join("repos"), db.clone(), config.pkg_workers, rt.clone())? - } - }; - //let mgr = Arc::new(mgr); - // - //for _ in 0..config.pkg_workers { - // let clone = Arc::clone(&mgr); - // - // rt.spawn(async move { clone.pkg_parse_task().await }); - //} - - Ok(Global { - config: config.clone(), - repo, - db, - pkg_filename_re: regex::Regex::new(PKG_FILENAME_REGEX).unwrap(), - }) -} - -async fn run(global: Global) -> crate::Result<()> { - let domain: String = format!("{}:{}", &global.config.domain, global.config.port) - .parse() - .unwrap(); - let listener = tokio::net::TcpListener::bind(domain).await?; - - let app = web::router(global); - - // run it with hyper on localhost:3000 - Ok(axum::serve(listener, app.into_make_service()) - .await - .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?) + cli.run().await } diff --git a/server/src/repo/actor.rs b/server/src/repo/actor.rs deleted file mode 100644 index 2c2fd74..0000000 --- a/server/src/repo/actor.rs +++ /dev/null @@ -1,245 +0,0 @@ -use super::{archive, package, Command, SharedState}; -use crate::db; - -use std::{ - path::PathBuf, - sync::{atomic::Ordering, Arc}, -}; - -use futures::StreamExt; -use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QuerySelect}; -use sea_query::Expr; -use tokio::{runtime, sync::mpsc}; -use uuid::Uuid; - -/// The actor is responsible for mutating the repositories. They receive their commands their -/// messages and process these commands in both a synchronous and asynchronous way. -pub struct Actor { - rt: runtime::Handle, - state: Arc, -} - -impl Actor { - pub fn new(rt: runtime::Handle, state: Arc) -> Self { - Self { - rt, - state: Arc::clone(&state), - } - } - - pub fn random_file_paths(&self) -> [PathBuf; C] { - std::array::from_fn(|_| { - let uuid: uuid::fmt::Simple = Uuid::new_v4().into(); - self.state.repos_dir.join(uuid.to_string()) - }) - } - - /// Run the main actor loop - pub fn run(self) { - while let Some(msg) = { - let mut rx = self.state.rx.lock().unwrap(); - rx.blocking_recv() - } { - match msg { - Command::ParsePkg(repo, path) => { - let _ = self.parse_pkg(repo, path); - - if self - .state - .repos - .blocking_read() - .get(&repo) - .map(|n| n.0.load(Ordering::SeqCst)) - == Some(0) - { - let _ = self.sync_repo(repo); - let _ = self.clean(); - } - } - Command::SyncRepo(repo) => { - let _ = self.sync_repo(repo); - } - Command::Clean => { - let _ = self.clean(); - } - } - } - } - - /// Parse a queued package for the given repository. - fn parse_pkg(&self, repo: i32, path: PathBuf) -> crate::Result<()> { - let pkg = package::Package::open(&path)?; - let pkg = self - .rt - .block_on(db::query::package::insert(&self.state.conn, repo, pkg))?; - let dest_path = self - .state - .repos_dir - .join(repo.to_string()) - .join(pkg.id.to_string()); - std::fs::rename(path, dest_path)?; - - tracing::info!( - "Added '{}-{}-{}' to repository {}", - pkg.name, - pkg.version, - pkg.arch, - repo, - ); - - self.state.repos.blocking_read().get(&repo).inspect(|n| { - n.0.fetch_sub(1, Ordering::SeqCst); - }); - - Ok(()) - } - - fn sync_repo(&self, repo: i32) -> crate::Result<()> { - let repos = self.state.repos.blocking_read(); - - if let Some(_guard) = repos.get(&repo).map(|n| n.1.lock()) { - let archs: Vec = self.rt.block_on( - db::Package::find() - .filter(db::package::Column::RepoId.eq(repo)) - .select_only() - .column(db::package::Column::Arch) - .distinct() - .into_tuple() - .all(&self.state.conn), - )?; - - for arch in archs { - self.generate_archives(repo, &arch)?; - } - } - - Ok(()) - } - - fn generate_archives(&self, repo: i32, arch: &str) -> crate::Result<()> { - let [tmp_ar_db_path, tmp_ar_files_path] = self.random_file_paths(); - - let mut ars = archive::RepoArchivesWriter::new( - &tmp_ar_db_path, - &tmp_ar_files_path, - self.random_file_paths(), - &self.rt, - &self.state.conn, - )?; - - let (tx, mut rx) = mpsc::channel(1); - - let conn = self.state.conn.clone(); - let query = db::query::package::pkgs_to_sync(&self.state.conn, repo, arch); - - // sea_orm needs its connections to be dropped inside an async context, so we spawn a task - // that streams the responses to the synchronous context via message passing - self.rt.spawn(async move { - match query.stream(&conn).await { - Ok(mut stream) => { - while let Some(res) = stream.next().await { - let is_err = res.is_err(); - let _ = tx.send(res).await; - - if is_err { - return; - } - } - } - Err(err) => { - let _ = tx.send(Err(err)).await; - } - } - }); - - let mut committed_ids: Vec = Vec::new(); - - while let Some(pkg) = rx.blocking_recv().transpose()? { - committed_ids.push(pkg.id); - ars.append_pkg(&pkg)?; - } - - ars.close()?; - - // Move newly generated package archives to their correct place - let repo_dir = self.state.repos_dir.join(repo.to_string()); - std::fs::rename(tmp_ar_db_path, repo_dir.join(format!("{}.db.tar.gz", arch)))?; - std::fs::rename( - tmp_ar_files_path, - repo_dir.join(format!("{}.files.tar.gz", arch)), - )?; - - // Update the state for the newly committed packages - self.rt.block_on( - db::Package::update_many() - .col_expr( - db::package::Column::State, - Expr::value(db::PackageState::Committed), - ) - .filter(db::package::Column::Id.is_in(committed_ids)) - .exec(&self.state.conn), - )?; - - tracing::info!("Package archives generated for repo {} ('{}')", repo, arch); - - Ok(()) - } - - fn clean(&self) -> crate::Result<()> { - let (tx, mut rx) = mpsc::channel(1); - let conn = self.state.conn.clone(); - let query = db::query::package::stale_pkgs(&self.state.conn); - - // sea_orm needs its connections to be dropped inside an async context, so we spawn a task - // that streams the responses to the synchronous context via message passing - self.rt.spawn(async move { - match query.stream(&conn).await { - Ok(mut stream) => { - while let Some(res) = stream.next().await { - let is_err = res.is_err(); - let _ = tx.send(res).await; - - if is_err { - return; - } - } - } - Err(err) => { - let _ = tx.send(Err(err)).await; - } - } - }); - - // Ids are monotonically increasing, so the max id suffices to know which packages to - // remove later - let mut max_id = -1; - let mut removed_pkgs = 0; - - while let Some(pkg) = rx.blocking_recv().transpose()? { - // Failing to remove the package file isn't the biggest problem - let _ = std::fs::remove_file( - self.state - .repos_dir - .join(pkg.repo_id.to_string()) - .join(pkg.id.to_string()), - ); - - if pkg.id > max_id { - max_id = pkg.id; - } - - removed_pkgs += 1; - } - - if removed_pkgs > 0 { - self.rt.block_on(db::query::package::delete_stale_pkgs( - &self.state.conn, - max_id, - ))?; - } - - tracing::info!("Cleaned up {removed_pkgs} old package(s)"); - - Ok(()) - } -} diff --git a/server/src/repo/archive.rs b/server/src/repo/archive.rs deleted file mode 100644 index 18e0801..0000000 --- a/server/src/repo/archive.rs +++ /dev/null @@ -1,224 +0,0 @@ -use crate::db; -use std::{ - io::Write, - path::{Path, PathBuf}, -}; - -use futures::StreamExt; -use libarchive::{ - write::{Builder, FileWriter, WriteEntry}, - Entry, WriteFilter, WriteFormat, -}; -use sea_orm::{ColumnTrait, DbConn, ModelTrait, QueryFilter, QuerySelect}; -use tokio::{runtime, sync::mpsc}; - -pub struct RepoArchivesWriter { - ar_db: FileWriter, - ar_files: FileWriter, - rt: runtime::Handle, - conn: DbConn, - tmp_paths: [PathBuf; 2], -} - -impl RepoArchivesWriter { - pub fn new( - ar_db_path: impl AsRef, - ar_files_path: impl AsRef, - tmp_paths: [impl AsRef; 2], - rt: &runtime::Handle, - conn: &sea_orm::DbConn, - ) -> crate::Result { - let ar_db = Self::open_ar(ar_db_path)?; - let ar_files = Self::open_ar(ar_files_path)?; - - Ok(Self { - ar_db, - ar_files, - rt: rt.clone(), - conn: conn.clone(), - tmp_paths: [ - tmp_paths[0].as_ref().to_path_buf(), - tmp_paths[1].as_ref().to_path_buf(), - ], - }) - } - - fn open_ar(path: impl AsRef) -> crate::Result { - let mut builder = Builder::new(); - builder.add_filter(WriteFilter::Gzip)?; - builder.set_format(WriteFormat::PaxRestricted)?; - - Ok(builder.open_file(path)?) - } - - fn append_entry( - ar: &mut FileWriter, - src_path: impl AsRef, - dest_path: impl AsRef, - ) -> crate::Result<()> { - let metadata = std::fs::metadata(&src_path)?; - let file_size = metadata.len(); - - let mut ar_entry = WriteEntry::new(); - ar_entry.set_filetype(libarchive::archive::FileType::RegularFile); - - ar_entry.set_pathname(dest_path); - ar_entry.set_mode(0o100644); - ar_entry.set_size(file_size.try_into().unwrap()); - - Ok(ar.append_path(&mut ar_entry, src_path)?) - } - - pub fn append_pkg(&mut self, pkg: &db::package::Model) -> crate::Result<()> { - self.write_desc(&self.tmp_paths[0], pkg)?; - self.write_files(&self.tmp_paths[1], pkg)?; - - let full_name = format!("{}-{}", pkg.name, pkg.version); - let dest_desc_path = format!("{}/desc", full_name); - let dest_files_path = format!("{}/files", full_name); - - Self::append_entry(&mut self.ar_db, &self.tmp_paths[0], &dest_desc_path)?; - Self::append_entry(&mut self.ar_files, &self.tmp_paths[0], &dest_desc_path)?; - Self::append_entry(&mut self.ar_files, &self.tmp_paths[1], &dest_files_path)?; - - Ok(()) - } - - /// Generate a "files" archive entry for the package in the given path - fn write_files(&self, path: impl AsRef, pkg: &db::package::Model) -> crate::Result<()> { - let mut f = std::io::BufWriter::new(std::fs::File::create(path)?); - - writeln!(f, "%FILES%")?; - - let (tx, mut rx) = mpsc::channel(1); - - let conn = self.conn.clone(); - let query = pkg.find_related(db::PackageFile); - - self.rt.spawn(async move { - match query.stream(&conn).await { - Ok(mut stream) => { - while let Some(res) = stream.next().await { - let is_err = res.is_err(); - let _ = tx.send(res).await; - - if is_err { - return; - } - } - } - Err(err) => { - let _ = tx.send(Err(err)).await; - } - } - }); - - while let Some(file) = rx.blocking_recv().transpose()? { - writeln!(f, "{}", file.path)?; - } - - f.flush()?; - Ok(()) - } - - fn write_desc(&self, path: impl AsRef, pkg: &db::package::Model) -> crate::Result<()> { - let mut f = std::io::BufWriter::new(std::fs::File::create(path)?); - - let filename = format!( - "{}-{}-{}.pkg.tar.{}", - pkg.name, pkg.version, pkg.arch, pkg.compression - ); - writeln!(f, "%FILENAME%\n{}", filename)?; - - let mut write_attr = |k: &str, v: &str| { - if !v.is_empty() { - writeln!(f, "\n%{}%\n{}", k, v) - } else { - Ok(()) - } - }; - - write_attr("NAME", &pkg.name)?; - write_attr("BASE", &pkg.base)?; - write_attr("VERSION", &pkg.version)?; - - if let Some(ref desc) = pkg.description { - write_attr("DESC", desc)?; - } - - let groups: Vec = self.rt.block_on( - pkg.find_related(db::PackageGroup) - .select_only() - .column(db::package_group::Column::Name) - .into_tuple() - .all(&self.conn), - )?; - - write_attr("GROUPS", &groups.join("\n"))?; - - write_attr("CSIZE", &pkg.c_size.to_string())?; - write_attr("ISIZE", &pkg.size.to_string())?; - write_attr("SHA256SUM", &pkg.sha256_sum)?; - - if let Some(ref url) = pkg.url { - write_attr("URL", url)?; - } - - let licenses: Vec = self.rt.block_on( - pkg.find_related(db::PackageLicense) - .select_only() - .column(db::package_license::Column::Name) - .into_tuple() - .all(&self.conn), - )?; - write_attr("LICENSE", &licenses.join("\n"))?; - - write_attr("ARCH", &pkg.arch)?; - - // TODO build date - write_attr( - "BUILDDATE", - &pkg.build_date.and_utc().timestamp().to_string(), - )?; - - if let Some(ref packager) = pkg.packager { - write_attr("PACKAGER", packager)?; - } - - let related = [ - ("REPLACES", db::PackageRelatedEnum::Replaces), - ("CONFLICTS", db::PackageRelatedEnum::Conflicts), - ("PROVIDES", db::PackageRelatedEnum::Provides), - ("DEPENDS", db::PackageRelatedEnum::Depend), - ("OPTDEPENDS", db::PackageRelatedEnum::Optdepend), - ("MAKEDEPENDS", db::PackageRelatedEnum::Makedepend), - ("CHECKDEPENDS", db::PackageRelatedEnum::Checkdepend), - ]; - - for (key, attr) in related.into_iter() { - let items: Vec = self.rt.block_on( - pkg.find_related(db::PackageRelated) - .filter(db::package_related::Column::Type.eq(attr)) - .select_only() - .column(db::package_related::Column::Name) - .into_tuple() - .all(&self.conn), - )?; - - write_attr(key, &items.join("\n"))?; - } - - f.flush()?; - Ok(()) - } - - pub fn close(&mut self) -> crate::Result<()> { - self.ar_db.close()?; - self.ar_files.close()?; - - let _ = std::fs::remove_file(&self.tmp_paths[0]); - let _ = std::fs::remove_file(&self.tmp_paths[1]); - - Ok(()) - } -} diff --git a/server/src/repo/handle.rs b/server/src/repo/handle.rs deleted file mode 100644 index bbcc153..0000000 --- a/server/src/repo/handle.rs +++ /dev/null @@ -1,144 +0,0 @@ -use super::{Command, SharedState}; -use crate::db; - -use std::{ - path::PathBuf, - sync::{atomic::Ordering, Arc}, -}; - -use sea_orm::{ - ActiveModelTrait, ColumnTrait, Condition, EntityTrait, NotSet, QueryFilter, QuerySelect, Set, -}; -use sea_query::Expr; -use uuid::Uuid; - -#[derive(Clone)] -pub struct Handle { - state: Arc, -} - -impl Handle { - pub fn new(state: &Arc) -> Self { - Self { - state: Arc::clone(state), - } - } - - pub fn random_file_paths(&self) -> [PathBuf; C] { - std::array::from_fn(|_| { - let uuid: uuid::fmt::Simple = Uuid::new_v4().into(); - self.state.repos_dir.join(uuid.to_string()) - }) - } - - pub async fn get_or_create_repo(&self, distro: &str, repo: &str) -> crate::Result { - let mut repos = self.state.repos.write().await; - - let distro_id: Option = db::Distro::find() - .filter(db::distro::Column::Name.eq(distro)) - .select_only() - .column(db::distro::Column::Id) - .into_tuple() - .one(&self.state.conn) - .await?; - - let distro_id = if let Some(id) = distro_id { - id - } else { - let new_distro = db::distro::ActiveModel { - id: NotSet, - name: Set(distro.to_string()), - description: NotSet, - }; - - new_distro.insert(&self.state.conn).await?.id - }; - - let repo_id: Option = db::Repo::find() - .filter(db::repo::Column::DistroId.eq(distro_id)) - .filter(db::repo::Column::Name.eq(repo)) - .select_only() - .column(db::repo::Column::Id) - .into_tuple() - .one(&self.state.conn) - .await?; - - let repo_id = if let Some(id) = repo_id { - id - } else { - let new_repo = db::repo::ActiveModel { - id: NotSet, - distro_id: Set(distro_id), - name: Set(repo.to_string()), - description: NotSet, - }; - let id = new_repo.insert(&self.state.conn).await?.id; - - tokio::fs::create_dir(self.state.repos_dir.join(id.to_string())).await?; - repos.insert(id, Default::default()); - - id - }; - - Ok(repo_id) - } - - pub async fn get_repo(&self, distro: &str, repo: &str) -> crate::Result> { - Ok(db::Repo::find() - .find_also_related(db::Distro) - .filter( - Condition::all() - .add(db::repo::Column::Name.eq(repo)) - .add(db::distro::Column::Name.eq(distro)), - ) - .one(&self.state.conn) - .await - .map(|res| res.map(|(repo, _)| repo.id))?) - } - - pub async fn remove_repo(&self, repo: i32) -> crate::Result<()> { - self.state.repos.write().await.remove(&repo); - db::Repo::delete_by_id(repo).exec(&self.state.conn).await?; - let _ = tokio::fs::remove_dir_all(self.state.repos_dir.join(repo.to_string())).await; - - Ok(()) - } - - /// Remove all packages in the repository that have a given arch. This method marks all - /// packages with the given architecture as "pending deletion", before performing a manual sync - /// & removal of stale packages. - pub async fn remove_repo_arch(&self, repo: i32, arch: &str) -> crate::Result<()> { - db::Package::update_many() - .col_expr( - db::package::Column::State, - Expr::value(db::PackageState::PendingDeletion), - ) - .filter( - Condition::all() - .add(db::package::Column::RepoId.eq(repo)) - .add(db::package::Column::Arch.eq(arch)), - ) - .exec(&self.state.conn) - .await?; - - self.queue_sync(repo).await; - self.queue_clean().await; - - Ok(()) - } - - pub async fn queue_pkg(&self, repo: i32, path: PathBuf) { - self.state.tx.send(Command::ParsePkg(repo, path)).unwrap(); - self.state.repos.read().await.get(&repo).inspect(|n| { - n.0.fetch_add(1, Ordering::SeqCst); - }); - } - - async fn queue_sync(&self, repo: i32) { - self.state.tx.send(Command::SyncRepo(repo)).unwrap(); - } - - async fn queue_clean(&self) { - self.state.tx.send(Command::Clean).unwrap(); - } -} diff --git a/server/src/repo/manager.rs b/server/src/repo/manager.rs new file mode 100644 index 0000000..1c5556e --- /dev/null +++ b/server/src/repo/manager.rs @@ -0,0 +1,309 @@ +use super::package::Package; +use libarchive::write::{Builder, WriteEntry}; +use libarchive::{Entry, WriteFilter, WriteFormat}; +use std::fs; +use std::io; +use std::path::{Path, PathBuf}; + +/// Overarching abstraction that orchestrates updating the repositories stored on the server +pub struct RepoGroupManager { + repo_dir: PathBuf, + pkg_dir: PathBuf, +} + +fn parse_pkg_filename(file_name: &str) -> (String, &str, &str, &str) { + let name_parts = file_name.split('-').collect::>(); + let name = name_parts[..name_parts.len() - 3].join("-"); + let version = name_parts[name_parts.len() - 3]; + let release = name_parts[name_parts.len() - 2]; + let (arch, _) = name_parts[name_parts.len() - 1].split_once('.').unwrap(); + + (name, version, release, arch) +} + +impl RepoGroupManager { + pub fn new, P2: AsRef>(repo_dir: P1, pkg_dir: P2) -> Self { + RepoGroupManager { + repo_dir: repo_dir.as_ref().to_path_buf(), + pkg_dir: pkg_dir.as_ref().to_path_buf(), + } + } + + pub fn sync(&mut self, repo: &str, arch: &str) -> io::Result<()> { + let subrepo_path = self.repo_dir.join(repo).join(arch); + + let mut ar_db = Builder::new(); + ar_db.add_filter(WriteFilter::Gzip)?; + ar_db.set_format(WriteFormat::PaxRestricted)?; + + let mut ar_files = Builder::new(); + ar_files.add_filter(WriteFilter::Gzip)?; + ar_files.set_format(WriteFormat::PaxRestricted)?; + + let mut ar_db = ar_db.open_file(subrepo_path.join(format!("{}.db.tar.gz", repo)))?; + let mut ar_files = + ar_files.open_file(subrepo_path.join(format!("{}.files.tar.gz", repo)))?; + + // All architectures should also include the "any" architecture, except for the "any" + // architecture itself. + let repo_any_dir = self.repo_dir.join(repo).join(super::ANY_ARCH); + + let any_entries_iter = if arch != super::ANY_ARCH && repo_any_dir.try_exists()? { + Some(repo_any_dir.read_dir()?) + } else { + None + } + .into_iter() + .flatten(); + + for entry in subrepo_path.read_dir()?.chain(any_entries_iter) { + let entry = entry?; + + if entry.file_type()?.is_dir() { + // The desc file needs to be added to both archives + let path_in_tar = PathBuf::from(entry.file_name()).join("desc"); + let src_path = entry.path().join("desc"); + let metadata = src_path.metadata()?; + + let mut ar_entry = WriteEntry::new(); + ar_entry.set_pathname(&path_in_tar); + // These small text files will definitely fit inside an i64 + ar_entry.set_size(metadata.len().try_into().unwrap()); + ar_entry.set_filetype(libarchive::archive::FileType::RegularFile); + ar_entry.set_mode(0o100644); + + ar_db.append_path(&mut ar_entry, &src_path)?; + ar_files.append_path(&mut ar_entry, src_path)?; + + // The files file is only required in the files database + let path_in_tar = PathBuf::from(entry.file_name()).join("files"); + let src_path = entry.path().join("files"); + let metadata = src_path.metadata()?; + + let mut ar_entry = WriteEntry::new(); + ar_entry.set_filetype(libarchive::archive::FileType::RegularFile); + ar_entry.set_pathname(&path_in_tar); + ar_entry.set_mode(0o100644); + // These small text files will definitely fit inside an i64 + ar_entry.set_size(metadata.len().try_into().unwrap()); + + ar_files.append_path(&mut ar_entry, src_path)?; + } + } + + ar_db.close()?; + ar_files.close()?; + + Ok(()) + } + + /// Synchronize all present architectures' db archives in the given repository. + pub fn sync_all(&mut self, repo: &str) -> io::Result<()> { + for entry in self.repo_dir.join(repo).read_dir()? { + let entry = entry?; + + if entry.file_type()?.is_dir() { + self.sync(repo, &entry.file_name().to_string_lossy())?; + } + } + + Ok(()) + } + + pub fn add_pkg_from_path>( + &mut self, + repo: &str, + path: P, + ) -> io::Result { + let pkg = Package::open(&path)?; + + self.add_pkg(repo, &pkg)?; + + // After successfully adding the package, we move it to the packages directory + let dest_pkg_path = self + .pkg_dir + .join(repo) + .join(&pkg.info.arch) + .join(pkg.file_name()); + + fs::create_dir_all(dest_pkg_path.parent().unwrap())?; + fs::rename(&path, dest_pkg_path)?; + + Ok(pkg) + } + + /// Add a package to the given repo, returning to what architectures the package was added. + pub fn add_pkg(&mut self, repo: &str, pkg: &Package) -> io::Result<()> { + // TODO + // * if arch is "any", check if package doesn't already exist for other architecture + // * if arch isn't "any", check if package doesn't already exist for "any" architecture + + // We first remove any existing version of the package + self.remove_pkg(repo, &pkg.info.arch, &pkg.info.name, false)?; + + // Write the `desc` and `files` metadata files to disk + let metadata_dir = self + .repo_dir + .join(repo) + .join(&pkg.info.arch) + .join(format!("{}-{}", pkg.info.name, pkg.info.version)); + + fs::create_dir_all(&metadata_dir)?; + + let mut desc_file = fs::File::create(metadata_dir.join("desc"))?; + pkg.write_desc(&mut desc_file)?; + + let mut files_file = fs::File::create(metadata_dir.join("files"))?; + pkg.write_files(&mut files_file)?; + + // If a package of type "any" is added, we need to update every existing database + if pkg.info.arch == super::ANY_ARCH { + self.sync_all(repo)?; + } else { + self.sync(repo, &pkg.info.arch)?; + } + + Ok(()) + } + + pub fn remove_repo(&mut self, repo: &str) -> io::Result { + let repo_dir = self.repo_dir.join(repo); + + if !repo_dir.exists() { + Ok(false) + } else { + fs::remove_dir_all(&repo_dir)?; + fs::remove_dir_all(self.pkg_dir.join(repo))?; + + Ok(true) + } + } + + pub fn remove_repo_arch(&mut self, repo: &str, arch: &str) -> io::Result { + let sub_path = PathBuf::from(repo).join(arch); + let repo_dir = self.repo_dir.join(&sub_path); + + if !repo_dir.exists() { + return Ok(false); + } + + fs::remove_dir_all(&repo_dir)?; + fs::remove_dir_all(self.pkg_dir.join(sub_path))?; + + // Removing the "any" architecture updates all other repositories + if arch == super::ANY_ARCH { + self.sync_all(repo)?; + } + + Ok(true) + } + + pub fn remove_pkg( + &mut self, + repo: &str, + arch: &str, + pkg_name: &str, + sync: bool, + ) -> io::Result { + let repo_arch_dir = self.repo_dir.join(repo).join(arch); + + if !repo_arch_dir.exists() { + return Ok(false); + } + + for entry in repo_arch_dir.read_dir()? { + let entry = entry?; + + // Make sure we skip the archive files + if !entry.metadata()?.is_dir() { + continue; + } + + let file_name = entry.file_name(); + let file_name = file_name.to_string_lossy(); + + // The directory name should only contain the name of the package. The last two parts + // when splitting on a dash are the pkgver and pkgrel, so we trim those + let name_parts = file_name.split('-').collect::>(); + let name = name_parts[..name_parts.len() - 2].join("-"); + + if name == pkg_name { + fs::remove_dir_all(entry.path())?; + + // Also remove the old package archive + let repo_arch_pkg_dir = self.pkg_dir.join(repo).join(arch); + + repo_arch_pkg_dir.read_dir()?.try_for_each(|res| { + res.and_then(|entry: fs::DirEntry| { + let file_name = entry.file_name(); + let file_name = file_name.to_string_lossy(); + let (name, _, _, _) = parse_pkg_filename(&file_name); + + if name == pkg_name { + fs::remove_file(entry.path()) + } else { + Ok(()) + } + }) + })?; + + if sync { + if arch == super::ANY_ARCH { + self.sync_all(repo)?; + } else { + self.sync(repo, arch)?; + } + } + + return Ok(true); + } + } + + Ok(false) + } + + /// Wrapper around `remove_pkg` that accepts a path relative to the package directory to a + /// package archive. + pub fn remove_pkg_from_path>( + &mut self, + path: P, + sync: bool, + ) -> io::Result> { + let path = path.as_ref(); + let components: Vec<_> = path.iter().collect(); + + if let [repo, _arch, file_name] = components[..] { + let full_path = self.pkg_dir.join(path); + + if full_path.try_exists()? { + let file_name = file_name.to_string_lossy(); + let (name, version, release, arch) = parse_pkg_filename(&file_name); + + let metadata_dir_name = format!("{}-{}-{}", name, version, release); + + // Remove package archive and entry in database + fs::remove_file(full_path)?; + fs::remove_dir_all(self.repo_dir.join(repo).join(arch).join(metadata_dir_name))?; + + if sync { + if arch == super::ANY_ARCH { + self.sync_all(&repo.to_string_lossy())?; + } else { + self.sync(&repo.to_string_lossy(), arch)?; + } + } + + Ok(Some(( + name, + version.to_string(), + release.to_string(), + arch.to_string(), + ))) + } else { + Ok(None) + } + } else { + Ok(None) + } + } +} diff --git a/server/src/repo/mod.rs b/server/src/repo/mod.rs index 25325c6..958420e 100644 --- a/server/src/repo/mod.rs +++ b/server/src/repo/mod.rs @@ -1,90 +1,7 @@ -mod actor; -mod archive; -mod handle; +pub mod manager; pub mod package; -pub use actor::Actor; -pub use handle::Handle; +pub use manager::RepoGroupManager; -use crate::db; - -use std::{ - collections::HashMap, - path::{Path, PathBuf}, - sync::{atomic::AtomicU32, Arc, Mutex}, -}; - -use sea_orm::{DbConn, EntityTrait, QuerySelect}; -use tokio::{ - runtime, - sync::{ - mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, - RwLock, - }, -}; - -pub enum Command { - ParsePkg(i32, PathBuf), - SyncRepo(i32), - Clean, -} - -type RepoState = (AtomicU32, Arc>); - -pub struct SharedState { - pub repos_dir: PathBuf, - pub conn: DbConn, - pub rx: Mutex>, - pub tx: UnboundedSender, - pub repos: RwLock>, -} - -impl SharedState { - pub fn new( - repos_dir: impl AsRef, - conn: DbConn, - repos: HashMap>)>, - ) -> Self { - let (tx, rx) = unbounded_channel(); - - Self { - repos_dir: repos_dir.as_ref().to_path_buf(), - conn, - rx: Mutex::new(rx), - tx, - repos: RwLock::new(repos), - } - } -} - -pub fn start( - repos_dir: impl AsRef, - conn: DbConn, - rt: runtime::Handle, - actors: u32, -) -> crate::Result { - std::fs::create_dir_all(repos_dir.as_ref())?; - - let mut repos = HashMap::new(); - let repo_ids: Vec = rt.block_on( - db::Repo::find() - .select_only() - .column(db::repo::Column::Id) - .into_tuple() - .all(&conn), - )?; - - for id in repo_ids { - repos.insert(id, Default::default()); - } - - let state = Arc::new(SharedState::new(repos_dir, conn, repos)); - - for _ in 0..actors { - let actor = Actor::new(rt.clone(), Arc::clone(&state)); - - std::thread::spawn(|| actor.run()); - } - - Ok(Handle::new(&state)) -} +pub const DB_FILE_EXTS: [&str; 4] = [".db", ".files", ".db.tar.gz", ".files.tar.gz"]; +pub const ANY_ARCH: &str = "any"; diff --git a/server/src/repo/package.rs b/server/src/repo/package.rs index 103a521..18c69c3 100644 --- a/server/src/repo/package.rs +++ b/server/src/repo/package.rs @@ -1,17 +1,15 @@ +use chrono::NaiveDateTime; +use libarchive::read::{Archive, Builder}; +use libarchive::{Entry, ReadFilter}; +use sea_orm::ActiveValue::Set; +use std::fmt; +use std::fs; +use std::io::{self, BufRead, BufReader, BufWriter, Read, Write}; +use std::path::{Path, PathBuf}; + use crate::db::entities::package; -use std::{ - fmt, fs, - io::{self, BufRead, BufReader, Read}, - path::{Path, PathBuf}, -}; - -use chrono::NaiveDateTime; -use libarchive::{ - read::{Archive, Builder}, - Entry, ReadFilter, -}; -use sea_orm::ActiveValue::Set; +const IGNORED_FILES: [&str; 5] = [".BUILDINFO", ".INSTALL", ".MTREE", ".PKGINFO", ".CHANGELOG"]; #[derive(Debug, Clone)] pub struct Package { @@ -48,18 +46,18 @@ pub struct PkgInfo { } #[derive(Debug, PartialEq, Eq)] -pub enum InvalidPkgInfoError { - Size, - BuildDate, - PgpSigSize, +pub enum ParsePkgInfoError { + InvalidSize, + InvalidBuildDate, + InvalidPgpSigSize, } -impl fmt::Display for InvalidPkgInfoError { +impl fmt::Display for ParsePkgInfoError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match self { - Self::Size => "invalid size", - Self::BuildDate => "invalid build date", - Self::PgpSigSize => "invalid pgp sig size", + Self::InvalidSize => "invalid size", + Self::InvalidBuildDate => "invalid build date", + Self::InvalidPgpSigSize => "invalid pgp sig size", }; write!(f, "{}", s) @@ -67,7 +65,7 @@ impl fmt::Display for InvalidPkgInfoError { } impl PkgInfo { - pub fn extend>(&mut self, line: S) -> Result<(), InvalidPkgInfoError> { + pub fn extend>(&mut self, line: S) -> Result<(), ParsePkgInfoError> { let line = line.as_ref(); if !line.starts_with('#') { @@ -77,21 +75,26 @@ impl PkgInfo { "pkgbase" => self.base = value.to_string(), "pkgver" => self.version = value.to_string(), "pkgdesc" => self.description = Some(value.to_string()), - "size" => self.size = value.parse().map_err(|_| InvalidPkgInfoError::Size)?, + "size" => { + self.size = value.parse().map_err(|_| ParsePkgInfoError::InvalidSize)? + } "url" => self.url = Some(value.to_string()), "arch" => self.arch = value.to_string(), "builddate" => { - let seconds: i64 = - value.parse().map_err(|_| InvalidPkgInfoError::BuildDate)?; - self.build_date = chrono::DateTime::from_timestamp_millis(seconds * 1000) - .ok_or(InvalidPkgInfoError::BuildDate)? - .naive_utc(); + let seconds: i64 = value + .parse() + .map_err(|_| ParsePkgInfoError::InvalidBuildDate)?; + self.build_date = NaiveDateTime::from_timestamp_millis(seconds * 1000) + .ok_or(ParsePkgInfoError::InvalidBuildDate)? } "packager" => self.packager = Some(value.to_string()), "pgpsig" => self.pgpsig = Some(value.to_string()), "pgpsigsize" => { - self.pgpsigsize = - Some(value.parse().map_err(|_| InvalidPkgInfoError::PgpSigSize)?) + self.pgpsigsize = Some( + value + .parse() + .map_err(|_| ParsePkgInfoError::InvalidPgpSigSize)?, + ) } "group" => self.groups.push(value.to_string()), "license" => self.licenses.push(value.to_string()), @@ -151,9 +154,11 @@ impl Package { let entry = entry?; let path_name = entry.pathname(); - if !path_name.starts_with('.') { + if !IGNORED_FILES.iter().any(|p| p == &path_name) { files.push(PathBuf::from(path_name)); - } else if path_name == ".PKGINFO" { + } + + if path_name == ".PKGINFO" { info = Some(PkgInfo::parse(entry)?); } } @@ -188,11 +193,79 @@ impl Package { // This unwrap should be safe, because we only allow passing through compressions with // known file extensions format!( - "{}.pkg.tar.{}", + "{}.pkg.tar{}", self.full_name(), self.compression.extension().unwrap() ) } + + /// Write the formatted desc file to the provided writer + pub fn write_desc(&self, w: &mut W) -> io::Result<()> { + // We write a lot of small strings to the writer, so wrapping it in a BufWriter is + // beneficial + let mut w = BufWriter::new(w); + + let info = &self.info; + + writeln!(w, "%FILENAME%\n{}", self.file_name())?; + + let mut write = |key: &str, value: &str| { + if !value.is_empty() { + writeln!(w, "\n%{}%\n{}", key, value) + } else { + Ok(()) + } + }; + + write("NAME", &info.name)?; + write("BASE", &info.base)?; + write("VERSION", &info.version)?; + + if let Some(ref description) = info.description { + write("DESC", description)?; + } + write("GROUPS", &info.groups.join("\n"))?; + write("CSIZE", &info.csize.to_string())?; + write("ISIZE", &info.size.to_string())?; + + write("SHA256SUM", &info.sha256sum)?; + + if let Some(ref url) = info.url { + write("URL", url)?; + } + + write("LICENSE", &info.licenses.join("\n"))?; + write("ARCH", &info.arch)?; + write("BUILDDATE", &info.build_date.timestamp().to_string())?; + + if let Some(ref packager) = info.packager { + write("PACKAGER", packager)?; + } + + write("REPLACES", &info.replaces.join("\n"))?; + write("CONFLICTS", &info.conflicts.join("\n"))?; + write("PROVIDES", &info.provides.join("\n"))?; + write("DEPENDS", &info.depends.join("\n"))?; + write("OPTDEPENDS", &info.optdepends.join("\n"))?; + write("MAKEDEPENDS", &info.makedepends.join("\n"))?; + write("CHECKDEPENDS", &info.checkdepends.join("\n"))?; + + Ok(()) + } + + pub fn write_files(&self, w: &mut W) -> io::Result<()> { + // We write a lot of small strings to the writer, so wrapping it in a BufWriter is + // beneficial + let mut w = BufWriter::new(w); + + writeln!(w, "%FILES%")?; + + for file in &self.files { + writeln!(w, "{}", file.to_string_lossy())?; + } + + Ok(()) + } } impl From for package::ActiveModel { diff --git a/server/src/util.rs b/server/src/util.rs deleted file mode 100644 index 9aad122..0000000 --- a/server/src/util.rs +++ /dev/null @@ -1,23 +0,0 @@ -pub struct Chunked { - iter: I, - chunk_size: usize, -} - -impl Chunked { - pub fn new>(into: T, chunk_size: usize) -> Self { - Self { - iter: into.into_iter(), - chunk_size, - } - } -} - -// https://users.rust-lang.org/t/how-to-breakup-an-iterator-into-chunks/87915/5 -impl Iterator for Chunked { - type Item = Vec; - - fn next(&mut self) -> Option { - Some(self.iter.by_ref().take(self.chunk_size).collect()) - .filter(|chunk: &Vec<_>| !chunk.is_empty()) - } -} diff --git a/server/src/web/api/distros.rs b/server/src/web/api/distros.rs new file mode 100644 index 0000000..d846398 --- /dev/null +++ b/server/src/web/api/distros.rs @@ -0,0 +1,50 @@ +use axum::{ + extract::{Path, Query, State}, + routing::get, + Json, Router, +}; + +use super::pagination::{self, PaginatedResponse}; +use crate::db; + +pub fn router() -> Router { + Router::new() + .route("/", get(get_distros).post(post_distro)) + .route("/:id", get(get_single_distro)) +} + +async fn get_distros( + State(global): State, + Query(pagination): Query, +) -> crate::Result>> { + let (total_pages, repos) = global + .db + .distro + .page( + pagination.per_page.unwrap_or(25), + pagination.page.unwrap_or(1) - 1, + ) + .await?; + Ok(Json(pagination.res(total_pages, repos))) +} + +async fn get_single_distro( + State(global): State, + Path(id): Path, +) -> crate::Result> { + let repo = global + .db + .distro + .by_id(id) + .await? + .ok_or(axum::http::StatusCode::NOT_FOUND)?; + + Ok(Json(repo)) +} + +async fn post_distro( + State(global): State, + Json(model): Json, +) -> crate::Result> { + Ok(Json(global.db.distro.insert_model(model).await?)) +} diff --git a/server/src/web/api/mod.rs b/server/src/web/api/mod.rs index 4678257..16940b4 100644 --- a/server/src/web/api/mod.rs +++ b/server/src/web/api/mod.rs @@ -1,63 +1,13 @@ +mod distros; +mod packages; mod pagination; +mod repos; -use crate::db; -use pagination::PaginatedResponse; - -use axum::{ - extract::{Path, Query, State}, - routing::get, - Json, Router, -}; +use axum::Router; pub fn router() -> Router { Router::new() - .route("/repos", get(get_repos)) - .route("/repos/:id", get(get_single_repo)) - .route("/packages", get(get_packages)) - .route("/packages/:id", get(get_single_package)) -} - -async fn get_repos( - State(global): State, - Query(pagination): Query, - Query(filter): Query, -) -> crate::Result>> { - let items = - db::query::repo::page(&global.db, pagination.per_page, pagination.page - 1, filter).await?; - - Ok(Json(pagination.res(items))) -} - -async fn get_single_repo( - State(global): State, - Path(id): Path, -) -> crate::Result> { - let repo = db::query::repo::by_id(&global.db, id) - .await? - .ok_or(axum::http::StatusCode::NOT_FOUND)?; - - Ok(Json(repo)) -} - -async fn get_packages( - State(global): State, - Query(pagination): Query, - Query(filter): Query, -) -> crate::Result>> { - let items = - db::query::package::page(&global.db, pagination.per_page, pagination.page - 1, filter) - .await?; - - Ok(Json(pagination.res(items))) -} - -async fn get_single_package( - State(global): State, - Path(id): Path, -) -> crate::Result> { - let entry = db::query::package::full(&global.db, id) - .await? - .ok_or(axum::http::StatusCode::NOT_FOUND)?; - - Ok(Json(entry)) + .nest("/distros", distros::router()) + .nest("/repos", repos::router()) + .nest("/packages", packages::router()) } diff --git a/server/src/web/api/packages.rs b/server/src/web/api/packages.rs new file mode 100644 index 0000000..c0c9fc3 --- /dev/null +++ b/server/src/web/api/packages.rs @@ -0,0 +1,44 @@ +use axum::{ + extract::{Path, Query, State}, + routing::get, + Json, Router, +}; + +use super::pagination::{self, PaginatedResponse}; +use crate::db; + +pub fn router() -> Router { + Router::new() + .route("/", get(get_packages)) + .route("/:id", get(get_single_package)) +} + +async fn get_packages( + State(global): State, + Query(pagination): Query, +) -> crate::Result>> { + let (total_pages, pkgs) = global + .db + .pkg + .page( + pagination.per_page.unwrap_or(25), + pagination.page.unwrap_or(1) - 1, + ) + .await?; + + Ok(Json(pagination.res(total_pages, pkgs))) +} + +async fn get_single_package( + State(global): State, + Path(id): Path, +) -> crate::Result> { + let entry = global + .db + .pkg + .full(id) + .await? + .ok_or(axum::http::StatusCode::NOT_FOUND)?; + + Ok(Json(entry)) +} diff --git a/server/src/web/api/pagination.rs b/server/src/web/api/pagination.rs index 3ede5bf..aa1e5cb 100644 --- a/server/src/web/api/pagination.rs +++ b/server/src/web/api/pagination.rs @@ -1,19 +1,12 @@ use serde::{Deserialize, Serialize}; +pub const DEFAULT_PAGE: u64 = 0; +pub const DEFAULT_PER_PAGE: u64 = 25; + #[derive(Deserialize)] pub struct Query { - #[serde(default = "default_page")] - pub page: u64, - #[serde(default = "default_per_page")] - pub per_page: u64, -} - -fn default_page() -> u64 { - 1 -} - -fn default_per_page() -> u64 { - 25 + pub page: Option, + pub per_page: Option, } #[derive(Serialize)] @@ -23,15 +16,21 @@ where { pub page: u64, pub per_page: u64, + pub total_pages: u64, pub count: usize, pub items: Vec, } impl Query { - pub fn res Serialize>(self, items: Vec) -> PaginatedResponse { + pub fn res Serialize>( + self, + total_pages: u64, + items: Vec, + ) -> PaginatedResponse { PaginatedResponse { - page: self.page, - per_page: self.per_page, + page: self.page.unwrap_or(DEFAULT_PAGE), + per_page: self.per_page.unwrap_or(DEFAULT_PER_PAGE), + total_pages, count: items.len(), items, } diff --git a/server/src/web/api/repos.rs b/server/src/web/api/repos.rs new file mode 100644 index 0000000..601ccb9 --- /dev/null +++ b/server/src/web/api/repos.rs @@ -0,0 +1,43 @@ +use axum::{ + extract::{Path, Query, State}, + routing::get, + Json, Router, +}; + +use super::pagination::{self, PaginatedResponse}; +use crate::db; + +pub fn router() -> Router { + Router::new() + .route("/", get(get_repos)) + .route("/:id", get(get_single_repo)) +} + +async fn get_repos( + State(global): State, + Query(pagination): Query, +) -> crate::Result>> { + let (total_pages, repos) = global + .db + .repo + .page( + pagination.per_page.unwrap_or(25), + pagination.page.unwrap_or(1) - 1, + ) + .await?; + Ok(Json(pagination.res(total_pages, repos))) +} + +async fn get_single_repo( + State(global): State, + Path(id): Path, +) -> crate::Result> { + let repo = global + .db + .repo + .by_id(id) + .await? + .ok_or(axum::http::StatusCode::NOT_FOUND)?; + + Ok(Json(repo)) +} diff --git a/server/src/web/mod.rs b/server/src/web/mod.rs index 48e9cbb..ce32a07 100644 --- a/server/src/web/mod.rs +++ b/server/src/web/mod.rs @@ -1,13 +1,19 @@ mod api; mod repo; -use axum::Router; +use axum::{Router, Server}; use tower_http::trace::TraceLayer; -pub fn router(global: crate::Global) -> Router { +pub fn app(global: crate::Global, api_key: &str) -> Router { Router::new() .nest("/api", api::router()) - .merge(repo::router(&global.config.api_key)) + .merge(repo::router(api_key)) .with_state(global) .layer(TraceLayer::new_for_http()) } + +pub async fn serve(app: Router, port: u16) -> Result<(), hyper::Error> { + Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap()) + .serve(app.into_make_service()) + .await +} diff --git a/server/src/web/repo.rs b/server/src/web/repo.rs index 84d80ca..9466af5 100644 --- a/server/src/web/repo.rs +++ b/server/src/web/repo.rs @@ -1,33 +1,41 @@ -use crate::{db, FsConfig}; +use std::path::PathBuf; -use axum::{ - body::Body, - extract::{Path, State}, - http::{Request, StatusCode}, - response::IntoResponse, - routing::{delete, get, post}, - Router, -}; -use futures::TryStreamExt; -use tokio_util::io::StreamReader; +use axum::body::Body; +use axum::extract::{BodyStream, Path, State}; +use axum::http::Request; +use axum::http::StatusCode; +use axum::response::IntoResponse; +use axum::routing::{delete, post}; +use axum::Router; +use futures::StreamExt; +use sea_orm::ModelTrait; +use std::sync::Arc; +use tokio::{fs, io::AsyncWriteExt}; use tower::util::ServiceExt; -use tower_http::{services::ServeFile, validate_request::ValidateRequestHeaderLayer}; +use tower_http::services::{ServeDir, ServeFile}; +use tower_http::validate_request::ValidateRequestHeaderLayer; +use uuid::Uuid; pub fn router(api_key: &str) -> Router { Router::new() .route( - "/:distro/:repo", + "/:repo", post(post_package_archive) .delete(delete_repo) .route_layer(ValidateRequestHeaderLayer::bearer(api_key)), ) .route( - "/:distro/:repo/:arch", + "/:repo/:arch", delete(delete_arch_repo).route_layer(ValidateRequestHeaderLayer::bearer(api_key)), ) // Routes added after the layer do not get that layer applied, so the GET requests will not // be authorized - .route("/:distro/:repo/:arch/:filename", get(get_file)) + .route( + "/:repo/:arch/:filename", + delete(delete_package) + .route_layer(ValidateRequestHeaderLayer::bearer(api_key)) + .get(get_file), + ) } /// Serve the package archive files and database archives. If files are requested for an @@ -35,74 +43,136 @@ pub fn router(api_key: &str) -> Router { /// is returned. async fn get_file( State(global): State, - Path((distro, repo, arch, file_name)): Path<(String, String, String, String)>, + Path((repo, arch, mut file_name)): Path<(String, String, String)>, req: Request, ) -> crate::Result { - if let Some(repo_id) = global.repo.get_repo(&distro, &repo).await? { - let file_name = - if file_name == format!("{}.db", repo) || file_name == format!("{}.db.tar.gz", repo) { - format!("{}.db.tar.gz", arch) - } else if file_name == format!("{}.files", repo) - || file_name == format!("{}.files.tar.gz", repo) - { - format!("{}.files.tar.gz", arch) - } else if let Some(m) = global.pkg_filename_re.captures(&file_name) { - // SAFETY: these unwraps cannot fail if the RegEx matched successfully - db::query::package::by_fields( - &global.db, - repo_id, - m.get(1).unwrap().as_str(), - m.get(2).unwrap().as_str(), - m.get(3).unwrap().as_str(), - m.get(4).unwrap().as_str(), - ) - .await? - .ok_or(StatusCode::NOT_FOUND)? - .id - .to_string() - } else { - return Err(StatusCode::NOT_FOUND.into()); - }; + let repo_dir = global.config.repo_dir.join(&repo).join(&arch); + let repo_exists = tokio::fs::try_exists(&repo_dir).await?; - match global.config.fs { - FsConfig::Local { data_dir } => { - let path = data_dir - .join("repos") - .join(repo_id.to_string()) - .join(file_name); - Ok(ServeFile::new(path).oneshot(req).await) - } + let res = if crate::repo::DB_FILE_EXTS + .iter() + .any(|ext| file_name.ends_with(ext)) + { + // Append tar extension to ensure we find the file + if !file_name.ends_with(".tar.gz") { + file_name.push_str(".tar.gz"); + }; + + if repo_exists { + ServeFile::new(repo_dir.join(file_name)).oneshot(req).await + } else { + let path = global + .config + .repo_dir + .join(repo) + .join(crate::repo::ANY_ARCH) + .join(file_name); + + ServeFile::new(path).oneshot(req).await } } else { - Err(StatusCode::NOT_FOUND.into()) - } + let any_file = global + .config + .pkg_dir + .join(repo) + .join(crate::repo::ANY_ARCH) + .join(file_name); + + if repo_exists { + ServeDir::new(global.config.pkg_dir) + .fallback(ServeFile::new(any_file)) + .oneshot(req) + .await + } else { + ServeFile::new(any_file).oneshot(req).await + } + }; + + Ok(res) } async fn post_package_archive( State(global): State, - Path((distro, repo)): Path<(String, String)>, - body: Body, -) -> crate::Result { - let repo_id = global.repo.get_or_create_repo(&distro, &repo).await?; + Path(repo): Path, + mut body: BodyStream, +) -> crate::Result<()> { + // We first stream the uploaded file to disk + let uuid: uuid::fmt::Simple = Uuid::new_v4().into(); + let path = global.config.pkg_dir.join(uuid.to_string()); + let mut f = fs::File::create(&path).await?; - let [tmp_path] = global.repo.random_file_paths(); - let mut tmp_file = tokio::fs::File::create(&tmp_path).await?; - let mut body = StreamReader::new(body.into_data_stream().map_err(std::io::Error::other)); - tokio::io::copy(&mut body, &mut tmp_file).await?; + while let Some(chunk) = body.next().await { + f.write_all(&chunk?).await?; + } - global.repo.queue_pkg(repo_id, tmp_path).await; + let clone = Arc::clone(&global.repo_manager); + let path_clone = path.clone(); + let repo_clone = repo.clone(); + let res = tokio::task::spawn_blocking(move || { + clone + .write() + .unwrap() + .add_pkg_from_path(&repo_clone, &path_clone) + }) + .await?; - Ok(StatusCode::ACCEPTED) + match res { + // Insert the newly added package into the database + Ok(pkg) => { + tracing::info!("Added '{}' to repository '{}'", pkg.file_name(), repo); + + // Query the repo for its ID, or create it if it does not already exist + let res = global.db.repo.by_name(&repo).await?; + + let repo_id = if let Some(repo_entity) = res { + repo_entity.id + } else { + global.db.repo.insert(&repo, None).await?.last_insert_id + }; + + // If the package already exists in the database, we remove it first + let res = global + .db + .pkg + .by_fields(repo_id, &pkg.info.name, None, &pkg.info.arch) + .await?; + + if let Some(entry) = res { + entry.delete(&global.db).await?; + } + + global.db.pkg.insert(repo_id, pkg).await?; + + Ok(()) + } + // Remove the uploaded file and return the error + Err(err) => { + tokio::fs::remove_file(path).await?; + + Err(err.into()) + } + } } async fn delete_repo( State(global): State, - Path((distro, repo)): Path<(String, String)>, + Path(repo): Path, ) -> crate::Result { - if let Some(repo) = global.repo.get_repo(&distro, &repo).await? { - global.repo.remove_repo(repo).await?; + let clone = Arc::clone(&global.repo_manager); - tracing::info!("Removed repository {repo}"); + let repo_clone = repo.clone(); + let repo_removed = + tokio::task::spawn_blocking(move || clone.write().unwrap().remove_repo(&repo_clone)) + .await??; + + if repo_removed { + let res = global.db.repo.by_name(&repo).await?; + + if let Some(repo_entry) = res { + repo_entry.delete(&global.db).await?; + } + + tracing::info!("Removed repository '{}'", repo); Ok(StatusCode::OK) } else { @@ -112,12 +182,67 @@ async fn delete_repo( async fn delete_arch_repo( State(global): State, - Path((distro, repo, arch)): Path<(String, String, String)>, + Path((repo, arch)): Path<(String, String)>, ) -> crate::Result { - if let Some(repo) = global.repo.get_repo(&distro, &repo).await? { - global.repo.remove_repo_arch(repo, &arch).await?; + let clone = Arc::clone(&global.repo_manager); - tracing::info!("Removed architecture '{arch}' from repository {repo}"); + let arch_clone = arch.clone(); + let repo_clone = repo.clone(); + let repo_removed = tokio::task::spawn_blocking(move || { + clone + .write() + .unwrap() + .remove_repo_arch(&repo_clone, &arch_clone) + }) + .await??; + + if repo_removed { + let res = global.db.repo.by_name(&repo).await?; + + if let Some(repo_entry) = res { + global.db.pkg.delete_with_arch(repo_entry.id, &arch).await?; + } + tracing::info!("Removed architecture '{}' from repository '{}'", arch, repo); + + Ok(StatusCode::OK) + } else { + Ok(StatusCode::NOT_FOUND) + } +} + +async fn delete_package( + State(global): State, + Path((repo, arch, file_name)): Path<(String, String, String)>, +) -> crate::Result { + let clone = Arc::clone(&global.repo_manager); + let path = PathBuf::from(&repo).join(arch).join(&file_name); + + let res = tokio::task::spawn_blocking(move || { + clone.write().unwrap().remove_pkg_from_path(path, true) + }) + .await??; + + if let Some((name, version, release, arch)) = res { + let res = global.db.repo.by_name(&repo).await?; + + if let Some(repo_entry) = res { + let res = global + .db + .pkg + .by_fields( + repo_entry.id, + &name, + Some(&format!("{}-{}", version, release)), + &arch, + ) + .await?; + + if let Some(entry) = res { + entry.delete(&global.db).await?; + } + } + + tracing::info!("Removed '{}' from repository '{}'", file_name, repo); Ok(StatusCode::OK) } else {