diff --git a/.env.example b/.env.example index 042ccd3..3492c0e 100644 --- a/.env.example +++ b/.env.example @@ -10,10 +10,13 @@ JWT_SECRET=changeme_generate_secure_secret_with_openssl_rand_hex_32 # Backend Configuration # ============================================ # Database connection string -DATABASE_URL=sqlite:/data/finance.db +# For development with docker-compose.dev.yml, use: +DATABASE_URL=postgres://csf_user:csf_password@postgres:5432/csf_core +# For production with SQLite, use: +# DATABASE_URL=sqlite:/data/finance.db # Rust logging level (trace, debug, info, warn, error) -RUST_LOG=info +RUST_LOG=debug # Frontend URL for CORS (must match the actual frontend URL) FRONTEND_URL=http://localhost:3000 diff --git a/.github/workflows/docker-build-manual.yml b/.github/workflows/docker-build-manual.yml index 26378b9..599affe 100644 --- a/.github/workflows/docker-build-manual.yml +++ b/.github/workflows/docker-build-manual.yml @@ -13,7 +13,7 @@ on: type: choice options: - both - - backend + - api-gateway - frontend permissions: @@ -21,8 +21,8 @@ permissions: packages: write jobs: - build-backend: - name: Build Backend ${{ matrix.arch }} + build-api-gateway: + name: Build API Gateway ${{ matrix.arch }} strategy: matrix: include: @@ -33,7 +33,7 @@ jobs: arch: arm64 runner: ubuntu-24.04-arm runs-on: ${{ matrix.runner }} - if: inputs.build_target == 'both' || inputs.build_target == 'backend' + if: inputs.build_target == 'both' || inputs.build_target == 'api-gateway' steps: - name: Checkout repository uses: actions/checkout@v4 @@ -53,20 +53,20 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Backend Docker image by digest + - name: Build and push API Gateway Docker image by digest id: build uses: docker/build-push-action@v5 with: - context: ./backend - file: ./backend/Dockerfile + context: ./control-plane/api-gateway + file: ./control-plane/api-gateway/Dockerfile push: true - outputs: type=registry,name=ghcr.io/${{ steps.repo.outputs.image_name }}-backend,push-by-digest=true + outputs: type=registry,name=ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway,push-by-digest=true cache-from: | - type=gha,scope=backend-${{ matrix.arch }} - type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-backend:buildcache-${{ matrix.arch }} + type=gha,scope=api-gateway-${{ matrix.arch }} + type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway:buildcache-${{ matrix.arch }} cache-to: | - type=gha,mode=max,scope=backend-${{ matrix.arch }} - type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-backend:buildcache-${{ matrix.arch }},mode=max + type=gha,mode=max,scope=api-gateway-${{ matrix.arch }} + type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway:buildcache-${{ matrix.arch }},mode=max platforms: ${{ matrix.platform }} provenance: false @@ -79,22 +79,22 @@ jobs: - name: Upload digest uses: actions/upload-artifact@v4 with: - name: digests-backend-${{ matrix.arch }} + name: digests-api-gateway-${{ matrix.arch }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 - merge-backend-manifest: - name: Create Backend Multi-Arch Manifest + merge-api-gateway-manifest: + name: Create API Gateway Multi-Arch Manifest runs-on: ubuntu-latest - needs: [build-backend] - if: inputs.build_target == 'both' || inputs.build_target == 'backend' + needs: [build-api-gateway] + if: inputs.build_target == 'both' || inputs.build_target == 'api-gateway' steps: - name: Download digests uses: actions/download-artifact@v4 with: path: /tmp/digests - pattern: digests-backend-* + pattern: digests-api-gateway-* merge-multiple: true - name: Set up Docker Buildx @@ -115,7 +115,7 @@ jobs: - name: Create manifest list and push working-directory: /tmp/digests run: | - IMAGE_NAME="ghcr.io/${{ steps.repo.outputs.image_name }}-backend" + IMAGE_NAME="ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway" docker buildx imagetools create \ -t ${IMAGE_NAME}:${{ inputs.version }} \ @@ -124,20 +124,20 @@ jobs: - name: Inspect image run: | - IMAGE_NAME="ghcr.io/${{ steps.repo.outputs.image_name }}-backend" + IMAGE_NAME="ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway" docker buildx imagetools inspect ${IMAGE_NAME}:${{ inputs.version }} - name: Summary run: | REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]') - echo "## 🐳 Backend Docker Image Built (Multi-Arch)" >> $GITHUB_STEP_SUMMARY + echo "## 🐳 API Gateway Docker Image Built (Multi-Arch)" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Platforms:** linux/amd64, linux/arm64" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "**Tags:**" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY - echo "ghcr.io/${REPO_LOWER}-backend:${{ inputs.version }}" >> $GITHUB_STEP_SUMMARY - echo "ghcr.io/${REPO_LOWER}-backend:manual-latest" >> $GITHUB_STEP_SUMMARY + echo "ghcr.io/${REPO_LOWER}-api-gateway:${{ inputs.version }}" >> $GITHUB_STEP_SUMMARY + echo "ghcr.io/${REPO_LOWER}-api-gateway:manual-latest" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY build-frontend: diff --git a/.github/workflows/main-release.yml b/.github/workflows/main-release.yml index b07e1f9..361f954 100644 --- a/.github/workflows/main-release.yml +++ b/.github/workflows/main-release.yml @@ -19,9 +19,9 @@ jobs: uses: ./.github/workflows/release.yml secrets: inherit - # Step 2: Build Backend Docker Images (Parallel by Architecture) - build-backend-docker: - name: Build Backend ${{ matrix.arch }} + # Step 2: Build API Gateway Docker Images (Parallel by Architecture) + build-api-gateway-docker: + name: Build API Gateway ${{ matrix.arch }} strategy: matrix: include: @@ -66,22 +66,22 @@ jobs: run: | VERSION="${{ needs.release.outputs.new_release_version }}" echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Building backend version: $VERSION for ${{ matrix.arch }}" + echo "Building api-gateway version: $VERSION for ${{ matrix.arch }}" - - name: Build and push Backend Docker image by digest + - name: Build and push API Gateway Docker image by digest id: build uses: docker/build-push-action@v5 with: - context: ./backend - file: ./backend/Dockerfile + context: ./control-plane/api-gateway + file: ./control-plane/api-gateway/Dockerfile push: true - outputs: type=registry,name=ghcr.io/${{ steps.repo.outputs.image_name }}-backend,push-by-digest=true + outputs: type=registry,name=ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway,push-by-digest=true cache-from: | - type=gha,scope=backend-${{ matrix.arch }} - type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-backend:buildcache-${{ matrix.arch }} + type=gha,scope=api-gateway-${{ matrix.arch }} + type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway:buildcache-${{ matrix.arch }} cache-to: | - type=gha,mode=max,scope=backend-${{ matrix.arch }} - type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-backend:buildcache-${{ matrix.arch }},mode=max + type=gha,mode=max,scope=api-gateway-${{ matrix.arch }} + type=registry,ref=ghcr.io/${{ steps.repo.outputs.image_name }}-api-gateway:buildcache-${{ matrix.arch }},mode=max platforms: ${{ matrix.platform }} provenance: false @@ -94,16 +94,16 @@ jobs: - name: Upload digest uses: actions/upload-artifact@v4 with: - name: digests-backend-${{ matrix.arch }} + name: digests-api-gateway-${{ matrix.arch }} path: /tmp/digests/* if-no-files-found: error retention-days: 1 - # Step 3: Create Backend Multi-Arch Manifest - merge-backend-manifest: - name: Create Backend Multi-Arch Manifest + # Step 3: Create API Gateway Multi-Arch Manifest + merge-api-gateway-manifest: + name: Create API Gateway Multi-Arch Manifest runs-on: ubuntu-latest - needs: [build-backend-docker, release] + needs: [build-api-gateway-docker, release] permissions: contents: read packages: write @@ -112,7 +112,7 @@ jobs: uses: actions/download-artifact@v4 with: path: /tmp/digests - pattern: digests-backend-* + pattern: digests-api-gateway-* merge-multiple: true - name: Set up Docker Buildx @@ -200,7 +200,7 @@ jobs: summary: name: Pipeline Summary runs-on: ubuntu-latest - needs: [release, build-backend-docker, build-frontend-docker] + needs: [release, build-api-gateway-docker, build-frontend-docker] if: always() steps: - name: Generate Summary diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 44fc320..db0d52f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -55,8 +55,8 @@ jobs: # Check if a release was published if grep -q "Published release" semantic-release-output.log; then echo "new_release_published=true" >> $GITHUB_OUTPUT - # Extract full version from the log (including beta, alpha, rc tags) - VERSION=$(grep "Published release" semantic-release-output.log | sed -n 's/.*Published release \([0-9.]*\(-[a-zA-Z0-9.]*\)\?\).*/\1/p') + # Extract version from the log + VERSION=$(grep "Published release" semantic-release-output.log | sed -n 's/.*Published release \([0-9.]*\).*/\1/p') echo "new_release_version=$VERSION" >> $GITHUB_OUTPUT echo "βœ… New release published: $VERSION" else diff --git a/.gitignore b/.gitignore index a9ffa90..402fdd8 100644 --- a/.gitignore +++ b/.gitignore @@ -16,9 +16,6 @@ devenv.local.nix finance.db -/backend/db/ -/backend/target/ - # Agent test directories /agent/test-agent*/ /agent/test-p2p/ diff --git a/CHANGELOG.md b/CHANGELOG.md index e9f6336..68802a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -407,6 +407,7 @@ All notable changes to CSF-Core will be documented in this file. * dashboard not working only test ([cfe6edb](https://github.com/CS-Foundry/CSF-Core/commit/cfe6edb108d5b48f144122e06160211fd9b06a61)) +>>>>>>> origin/main ## [0.2.2](https://github.com/CS-Foundry/CSF-Core/compare/v0.2.1...v0.2.2) (2026-01-05) diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..176af29 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,5470 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "agent" +version = "0.2.2" +dependencies = [ + "anyhow", + "dotenvy", + "shared", + "tokio", + "tracing", +] + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "aliasable" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" + +[[package]] +name = "aligned" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" +dependencies = [ + "as-slice", +] + +[[package]] +name = "aligned-vec" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b" +dependencies = [ + "equator", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "api-gateway" +version = "0.2.2" +dependencies = [ + "anyhow", + "async-trait", + "axum", + "base64 0.22.1", + "bcrypt", + "bollard", + "chrono", + "cookie", + "dotenvy", + "entity", + "futures-util", + "http 1.4.0", + "hyper 1.8.1", + "hyper-util", + "image", + "jsonwebtoken", + "migration", + "qrcode", + "rand 0.8.5", + "reqwest", + "rsa", + "sea-orm", + "serde", + "serde_json", + "sha1", + "sha2", + "shared", + "sysinfo", + "thiserror 1.0.69", + "tokio", + "totp-rs", + "tower-http", + "tracing", + "tracing-subscriber", + "utoipa", + "utoipa-swagger-ui", + "uuid", +] + +[[package]] +name = "arbitrary" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "async-attributes" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.5.0", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", + "tokio", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener 5.4.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" +dependencies = [ + "async-attributes", + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[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.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "av-scenechange" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f321d77c20e19b92c39e7471cf986812cbb46659d2af674adc4331ef3f18394" +dependencies = [ + "aligned", + "anyhow", + "arg_enum_proc_macro", + "arrayvec", + "log", + "num-rational", + "num-traits", + "pastey", + "rayon", + "thiserror 2.0.18", + "v_frame", + "y4m", +] + +[[package]] +name = "av1-grain" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfddb07216410377231960af4fcab838eaa12e013417781b78bd95ee22077f8" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47c8fbc0f831f4519fe8b810b6a7a91410ec83031b8233f730a0480029f6a23f" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.2", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "base32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[package]] +name = "bcrypt" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e65938ed058ef47d92cf8b346cc76ef48984572ade631927e9937b5ffc7662c7" +dependencies = [ + "base64 0.22.1", + "blowfish", + "getrandom 0.2.17", + "subtle", + "zeroize", +] + +[[package]] +name = "bigdecimal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6867f1565b3aad85681f1015055b087fcfd840d6aeee6eee7f2da317603695" +dependencies = [ + "autocfg", + "libm", + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bit_field" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +dependencies = [ + "serde_core", +] + +[[package]] +name = "bitstream-io" +version = "4.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757" +dependencies = [ + "core2", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" +dependencies = [ + "async-channel 2.5.0", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + +[[package]] +name = "bollard" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41711ad46fda47cd701f6908e59d1bd6b9a2b7464c0d0aeab95c6d37096ff8a" +dependencies = [ + "base64 0.22.1", + "bollard-stubs", + "bytes", + "futures-core", + "futures-util", + "hex", + "http 1.4.0", + "http-body-util", + "hyper 1.8.1", + "hyper-named-pipe", + "hyper-util", + "hyperlocal", + "log", + "pin-project-lite", + "serde", + "serde_derive", + "serde_json", + "serde_repr", + "serde_urlencoded", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "tower-service", + "url", + "winapi", +] + +[[package]] +name = "bollard-stubs" +version = "1.45.0-rc.26.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d7c5415e3a6bc6d3e99eff6268e488fd4ee25e7b28c10f08fa6760bd9de16e4" +dependencies = [ + "serde", + "serde_repr", + "serde_with", +] + +[[package]] +name = "borsh" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "built" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "cc" +version = "1.2.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "4.5.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75ca66430e33a14957acc24c5077b503e7d374151b2b4b3a10c83b4ceb4be0e" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793207c7fa6300a0608d1080b858e5fdbe713cdc1c8db9fb17777d8a13e63df0" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "clap_lex" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" + +[[package]] +name = "cli" +version = "0.2.2" +dependencies = [ + "anyhow", + "dotenvy", + "shared", + "tokio", + "tracing", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.114", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "entity" +version = "0.2.2" +dependencies = [ + "chrono", + "sea-orm", + "serde", + "serde_json", + "utoipa", + "uuid", +] + +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener 5.4.1", + "pin-project-lite", +] + +[[package]] +name = "exr" +version = "1.74.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4300e043a56aa2cb633c01af81ca8f699a321879a7854d3896a0ba89056363be" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "failover-controller" +version = "0.2.2" +dependencies = [ + "anyhow", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" +dependencies = [ + "fax_derive", +] + +[[package]] +name = "fax_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "flate2" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "gif" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.13.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.4.0", + "indexmap 2.13.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.4.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.4.0", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2 0.4.13", + "http 1.4.0", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-named-pipe" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b7d8abf35697b81a825e386fc151e0d503e8cb5fcb93cc8669c376dfd6f278" +dependencies = [ + "hex", + "hyper 1.8.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", + "winapi", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.32", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-util" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "hyper 1.8.1", + "libc", + "pin-project-lite", + "socket2 0.6.2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "hyperlocal" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5ce3b994526b3cd75578e62554abd09f0899d6206de48b3e96ab34ccc8c7" +dependencies = [ + "hex", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "image" +version = "0.25.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "moxcms", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core 0.5.1", + "zune-jpeg 0.5.12", +] + +[[package]] +name = "image-webp" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "inherent" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c727f80bfa4a6c6e2508d2f05b6f4bfce242030bd88ed15ae5331c5b5d30fba7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "9.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +dependencies = [ + "base64 0.22.1", + "js-sys", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lebe" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.10.0", + "libc", + "redox_syscall 0.7.0", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +dependencies = [ + "value-bag", +] + +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "migration" +version = "0.2.2" +dependencies = [ + "async-std", + "sea-orm-migration", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "moxcms" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "ntapi" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ouroboros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" +dependencies = [ + "aliasable", + "ouroboros_macro", + "static_assertions", +] + +[[package]] +name = "ouroboros_macro" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.18", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pastey" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" + +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64 0.22.1", + "serde_core", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pgvector" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc58e2d255979a31caa7cabfa7aac654af0354220719ab7a68520ae7a91e8c0b" +dependencies = [ + "serde", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.10.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +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.114", + "version_check", + "yansi", +] + +[[package]] +name = "profiling" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +dependencies = [ + "quote", + "syn 2.0.114", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "pxfm" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7186d3822593aa4393561d186d1393b3923e9d6163d3fbfd6e825e3e6cf3e6a8" +dependencies = [ + "num-traits", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "qrcode" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68782463e408eb1e668cf6152704bd856c78c5b6417adaee3203d8f4c1fc9ec" +dependencies = [ + "image", +] + +[[package]] +name = "qrcodegen" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" + +[[package]] +name = "qrcodegen-image" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99530e45ded4640c0eab5420fc60f9a0ec1be51a22e49cc8578b9a0d8be70712" +dependencies = [ + "base64 0.22.1", + "image", + "qrcodegen", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rav1e" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b" +dependencies = [ + "aligned-vec", + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av-scenechange", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "paste", + "profiling", + "rand 0.9.2", + "rand_chacha 0.9.0", + "simd_helpers", + "thiserror 2.0.18", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "registry" +version = "0.2.2" +dependencies = [ + "anyhow", + "dotenvy", + "shared", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rgb" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rkyv" +version = "0.7.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2297bf9c81a3f0dc96bc9521370b88f054168c29826a75e89c55ff196e7ed6a1" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d7b42d4b8d06048d3ac8db0eb31bcb942cbeb709f0b5f2b2ebde398d3038f5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "sha2", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rust-embed" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.114", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" +dependencies = [ + "sha2", + "walkdir", +] + +[[package]] +name = "rust_decimal" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scheduler" +version = "0.2.2" +dependencies = [ + "anyhow", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdn-controller" +version = "0.2.2" +dependencies = [ + "anyhow", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "sea-bae" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25" +dependencies = [ + "heck 0.4.1", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "sea-orm" +version = "1.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d945f62558fac19e5988680d2fdf747b734c2dbc6ce2cb81ba33ed8dde5b103" +dependencies = [ + "async-stream", + "async-trait", + "bigdecimal", + "chrono", + "derive_more", + "futures-util", + "log", + "ouroboros", + "pgvector", + "rust_decimal", + "sea-orm-macros", + "sea-query", + "sea-query-binder", + "serde", + "serde_json", + "sqlx", + "strum", + "thiserror 2.0.18", + "time", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "sea-orm-cli" +version = "1.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94492e2ab6c045b4cc38013809ce255d14c3d352c9f0d11e6b920e2adc948ad" +dependencies = [ + "chrono", + "clap", + "dotenvy", + "glob", + "regex", + "sea-schema", + "sqlx", + "tokio", + "tracing", + "tracing-subscriber", + "url", +] + +[[package]] +name = "sea-orm-macros" +version = "1.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c2e64a50a9cc8339f10a27577e10062c7f995488e469f2c95762c5ee847832" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "sea-bae", + "syn 2.0.114", + "unicode-ident", +] + +[[package]] +name = "sea-orm-migration" +version = "1.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7315c0cadb7e60fb17ee2bb282aa27d01911fc2a7e5836ec1d4ac37d19250bb4" +dependencies = [ + "async-trait", + "clap", + "dotenvy", + "sea-orm", + "sea-orm-cli", + "sea-schema", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "sea-query" +version = "0.32.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a5d1c518eaf5eda38e5773f902b26ab6d5e9e9e2bb2349ca6c64cf96f80448c" +dependencies = [ + "bigdecimal", + "chrono", + "inherent", + "ordered-float", + "rust_decimal", + "sea-query-derive", + "serde_json", + "time", + "uuid", +] + +[[package]] +name = "sea-query-binder" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0019f47430f7995af63deda77e238c17323359af241233ec768aba1faea7608" +dependencies = [ + "bigdecimal", + "chrono", + "rust_decimal", + "sea-query", + "serde_json", + "sqlx", + "time", + "uuid", +] + +[[package]] +name = "sea-query-derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae0cbad6ab996955664982739354128c58d16e126114fe88c2a493642502aab" +dependencies = [ + "darling", + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.114", + "thiserror 2.0.18", +] + +[[package]] +name = "sea-schema" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2239ff574c04858ca77485f112afea1a15e53135d3097d0c86509cef1def1338" +dependencies = [ + "futures", + "sea-query", + "sea-query-binder", + "sea-schema-derive", + "sqlx", +] + +[[package]] +name = "sea-schema-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.10.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.13.0", + "schemars 0.9.0", + "schemars 1.2.0", + "serde_core", + "serde_json", + "time", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shared" +version = "0.2.2" +dependencies = [ + "anyhow", + "async-trait", + "dotenvy", + "migration", + "sea-orm", + "sea-orm-migration", + "serde", + "thiserror 1.0.69", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "simple_asn1" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror 2.0.18", + "time", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64 0.22.1", + "bigdecimal", + "bytes", + "chrono", + "crc", + "crossbeam-queue", + "either", + "event-listener 5.4.1", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.5", + "hashlink", + "indexmap 2.13.0", + "log", + "memchr", + "once_cell", + "percent-encoding", + "rust_decimal", + "rustls", + "serde", + "serde_json", + "sha2", + "smallvec", + "thiserror 2.0.18", + "time", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", + "webpki-roots 0.26.11", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.114", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck 0.5.0", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.114", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +dependencies = [ + "atoi", + "base64 0.22.1", + "bigdecimal", + "bitflags 2.10.0", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "rust_decimal", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.18", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +dependencies = [ + "atoi", + "base64 0.22.1", + "bigdecimal", + "bitflags 2.10.0", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand 0.8.5", + "rust_decimal", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.18", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror 2.0.18", + "time", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "sysinfo" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tiff" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" +dependencies = [ + "fax", + "flate2", + "half", + "quick-error", + "weezl", + "zune-jpeg 0.4.21", +] + +[[package]] +name = "time" +version = "0.3.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78cc610bac2dcee56805c99642447d4c5dbde4d01f752ffea0199aee1f601dc4" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.6.2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] + +[[package]] +name = "totp-rs" +version = "5.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f124352108f58ef88299e909f6e9470f1cdc8d2a1397963901b4a6366206bf72" +dependencies = [ + "base32", + "constant_time_eq", + "hmac", + "qrcodegen-image", + "sha1", + "sha2", + "url", + "urlencoding", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 1.0.2", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +dependencies = [ + "bitflags 2.10.0", + "bytes", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "utoipa" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" +dependencies = [ + "indexmap 2.13.0", + "serde", + "serde_json", + "utoipa-gen", +] + +[[package]] +name = "utoipa-gen" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 2.0.114", + "uuid", +] + +[[package]] +name = "utoipa-swagger-ui" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b39868d43c011961e04b41623e050aedf2cc93652562ff7935ce0f819aaf2da" +dependencies = [ + "axum", + "mime_guess", + "regex", + "rust-embed", + "serde", + "serde_json", + "utoipa", + "zip", +] + +[[package]] +name = "uuid" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "v_frame" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "666b7727c8875d6ab5db9533418d7c764233ac9c0cff1d469aec8fa127597be2" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "value-bag" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "volume-manager" +version = "0.2.2" +dependencies = [ + "anyhow", + "dotenvy", + "shared", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[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.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[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.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.114", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.5", +] + +[[package]] +name = "webpki-roots" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + +[[package]] +name = "whoami" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" +dependencies = [ + "libredox", + "wasite", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link", + "windows-result 0.4.1", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +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.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "y4m" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5a4b21e1a62b67a2970e6831bc091d7b87e119e7f9791aef9702e3bef04448" + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7456cf00f0685ad319c5b1693f291a650eaf345e941d082fc4e03df8a03996ac" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1328722bbf2115db7e19d69ebcc15e795719e2d66b60827c6a69a117365e37a0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + +[[package]] +name = "zmij" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1966f8ac2c1f76987d69a74d0e0f929241c10e78136434e3be70ff7f58f64214" + +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9" + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zune-jpeg" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" +dependencies = [ + "zune-core 0.4.12", +] + +[[package]] +name = "zune-jpeg" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "410e9ecef634c709e3831c2cfdb8d9c32164fae1c67496d5b68fff728eec37fe" +dependencies = [ + "zune-core 0.5.1", +] diff --git a/backend/Cargo.toml b/Cargo.toml similarity index 51% rename from backend/Cargo.toml rename to Cargo.toml index de04193..f31adcd 100644 --- a/backend/Cargo.toml +++ b/Cargo.toml @@ -1,46 +1,81 @@ -[package] -name = "backend" -version = "0.1.12" +[workspace] +resolver = "2" +members = [ + "agent", + "cli", + "control-plane/api-gateway", + "control-plane/scheduler", + "control-plane/failover-controller", + "control-plane/sdn-controller", + "control-plane/volume-manager", + "control-plane/registry", + "control-plane/shared/entity", + "control-plane/shared/migration", + "control-plane/shared/shared", +] + +[workspace.package] +version = "0.2.2" edition = "2021" +authors = ["CS-Foundry"] +license = "SEE LICENSE IN LICENSE" +repository = "https://github.com/CS-Foundry/CSF-Core" -[dependencies] +[workspace.dependencies] +# Async runtime tokio = { version = "1", features = ["full"] } -sea-orm = { version = "1.1.0", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ] } -dotenvy = "0.15" -migration = { path = "migration" } -entity = { path = "entity" } +async-trait = "0.1" + +# Database +sea-orm = { version = "1.1.0", features = ["sqlx-postgres", "runtime-tokio-rustls", "macros"] } +sea-orm-migration = { version = "1.1.0", features = ["runtime-tokio-rustls", "sqlx-postgres"] } + +# Web framework axum = "0.7.5" tower-http = { version = "0.5.2", features = ["cors", "trace"] } +hyper = "1.5" +hyper-util = { version = "0.1", features = ["client", "client-legacy", "http1", "http2", "tokio"] } +http = "1.1" + +# Serialization serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.145" + +# Logging & Tracing tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } -serde_json = "1.0.145" + +# Security jsonwebtoken = "9.3.0" bcrypt = "0.15" rsa = { version = "0.9", features = ["sha2"] } -rand = "0.8" -chrono = { version = "0.4", features = ["serde"] } +totp-rs = { version = "5.6", features = ["qr", "otpauth"] } + +# Utilities uuid = { version = "1.0", features = ["v4", "serde"] } +chrono = { version = "0.4", features = ["serde"] } +dotenvy = "0.15" +anyhow = "1.0" +thiserror = "1.0" + +# OpenAPI +utoipa = { version = "4.2", features = ["axum_extras", "uuid", "chrono"] } +utoipa-swagger-ui = { version = "6.0", features = ["axum"] } + +# Other +rand = "0.8" base64 = "0.22" sha1 = "0.10" sha2 = "0.10" -thiserror = "1.0" -async-trait = "0.1" -utoipa = { version = "4.2", features = ["axum_extras"] } -utoipa-swagger-ui = { version = "6.0", features = ["axum"] } cookie = { version = "0.18.1", features = ["percent-encode"] } -hyper = "1.5" -hyper-util = { version = "0.1", features = ["client", "client-legacy", "http1", "http2", "tokio"] } -http = "1.1" -totp-rs = { version = "5.6", features = ["qr", "otpauth"] } qrcode = "0.14" image = "0.25" sysinfo = "0.32" -anyhow = "1.0" bollard = "0.17" futures-util = "0.3" reqwest = { version = "0.11", features = ["json"] } -[features] -default = [] -vendored-openssl = [] +[profile.release] +opt-level = 3 +lto = true +codegen-units = 1 diff --git a/DEV_README.md b/DEV_README.md new file mode 100644 index 0000000..5a391d8 --- /dev/null +++ b/DEV_README.md @@ -0,0 +1,287 @@ +# CSF-Core Development Guide + +## πŸ—οΈ Multi-Crate Workspace Structure + +This project is organized as a Rust workspace with multiple crates: + +``` +crates/ +β”œβ”€β”€ agent/ # Resource monitoring and task execution agent +β”œβ”€β”€ cli/ # Command-line interface tool +β”œβ”€β”€ control-plane/ # Main backend API server +β”œβ”€β”€ entity/ # Database entity definitions (SeaORM) +β”œβ”€β”€ migration/ # Database migrations +└── shared/ # Shared utilities (logger, DB connections) +``` + +## πŸš€ Quick Start + +### Prerequisites + +- Docker and Docker Compose +- Rust 1.75+ (for local development) +- PostgreSQL 16 (if running locally) + +### Development with Docker Compose + +1. **Clone and setup:** + + ```bash + git clone https://github.com/CS-Foundry/CSF-Core.git + cd CSF-Core + cp .env.example .env + ``` + +2. **Edit `.env` file** with your configuration + +3. **Start all services:** + + ```bash + docker-compose -f docker-compose.dev.yml up + ``` + + This will start: + - PostgreSQL database (port 5432) + - Control Plane API (port 8000) + - Agent (background service) + - Frontend (port 3000) + +4. **Run CLI separately** (optional): + ```bash + docker-compose -f docker-compose.dev.yml --profile tools up cli + ``` + +### Local Development (without Docker) + +1. **Install dependencies:** + + ```bash + # Install Rust + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + + # Install cargo-watch for auto-reload + cargo install cargo-watch + ``` + +2. **Setup PostgreSQL:** + + ```bash + # Start PostgreSQL (example using Docker) + docker run -d \ + --name csf-postgres \ + -e POSTGRES_USER=csf_user \ + -e POSTGRES_PASSWORD=csf_password \ + -e POSTGRES_DB=csf_core \ + -p 5432:5432 \ + postgres:16-alpine + ``` + +3. **Configure environment:** + + ```bash + cp .env.example .env + # Edit .env with your settings + ``` + +4. **Run migrations:** + + ```bash + cargo run --bin control-plane + # Migrations run automatically on startup + ``` + +5. **Run individual services:** + + **Control Plane:** + + ```bash + cargo watch -x "run --bin control-plane" + ``` + + **Agent:** + + ```bash + cargo watch -x "run --bin agent" + ``` + + **CLI:** + + ```bash + cargo run --bin csf + ``` + +## πŸ“¦ Workspace Crates + +### Control Plane + +Main backend API server with: + +- REST API endpoints +- JWT authentication +- Docker container management +- System monitoring +- Swagger UI documentation at `/swagger-ui` + +### Agent + +Resource monitoring agent that: + +- Reports system metrics +- Executes tasks from control plane +- Manages local containers +- Provides heartbeat monitoring + +### CLI + +Command-line interface for: + +- User management +- Resource configuration +- System administration +- Deployment tools + +### Entity + +SeaORM entity definitions for all database tables + +### Migration + +Database migration scripts managed by SeaORM + +### Shared + +Common utilities: + +- Logger initialization (tracing) +- Database connection management +- Shared types and traits + +## πŸ”§ Development Commands + +### Build entire workspace: + +```bash +cargo build --workspace +``` + +### Run tests: + +```bash +cargo test --workspace +``` + +### Check code: + +```bash +cargo check --workspace +``` + +### Format code: + +```bash +cargo fmt --all +``` + +### Lint code: + +```bash +cargo clippy --workspace -- -D warnings +``` + +### Run specific binary: + +```bash +# Control Plane +cargo run --bin control-plane + +# Agent +cargo run --bin agent + +# CLI +cargo run --bin csf +``` + +## πŸ—„οΈ Database Management + +### Run migrations: + +Migrations run automatically when control-plane starts, or manually: + +```bash +cd crates/migration +cargo run +``` + +### Create new migration: + +```bash +cd crates/migration +sea-orm-cli migrate generate +``` + +### Generate entities from database: + +```bash +sea-orm-cli generate entity \ + -u postgres://csf_user:csf_password@localhost:5432/csf_core \ + -o crates/entity/src/entities +``` + +## πŸ“Š API Documentation + +Once the control-plane is running, visit: + +- Swagger UI: http://localhost:8000/swagger-ui +- OpenAPI JSON: http://localhost:8000/api-docs/openapi.json + +## πŸ› Debugging + +### View logs: + +```bash +# All services +docker-compose -f docker-compose.dev.yml logs -f + +# Specific service +docker-compose -f docker-compose.dev.yml logs -f control-plane +``` + +### Access database: + +```bash +docker exec -it csf-postgres-dev psql -U csf_user -d csf_core +``` + +### Check service status: + +```bash +docker-compose -f docker-compose.dev.yml ps +``` + +## πŸ” Environment Variables + +| Variable | Description | Default | +| ------------------- | ------------------------------------------- | ----------------------- | +| `DATABASE_URL` | PostgreSQL connection string | Required | +| `JWT_SECRET` | Secret for JWT tokens | Required | +| `RUST_LOG` | Log level (error, warn, info, debug, trace) | `info` | +| `RSA_KEY_SIZE` | RSA key size for encryption | `2048` | +| `CONTROL_PLANE_URL` | URL to control plane API | `http://localhost:8000` | + +## πŸ“ Notes + +- **Agent and CLI**: Currently have placeholder implementations with test logs +- **Hot reload**: All services support hot reload in development mode using `cargo-watch` +- **Database**: Automatically creates tables and runs migrations on startup +- **Docker volumes**: Data persists across container restarts + +## 🀝 Contributing + +1. Create a feature branch +2. Make your changes +3. Run tests and linting +4. Submit a pull request + +## πŸ“„ License + +MIT License - see LICENSE file for details diff --git a/MANUAL_UPDATE_FIX.md b/MANUAL_UPDATE_FIX.md deleted file mode 100644 index 88574b2..0000000 --- a/MANUAL_UPDATE_FIX.md +++ /dev/null @@ -1,335 +0,0 @@ -# πŸ”§ Manuelle Update-Fix Anleitung fΓΌr Ubuntu Server - -## Problem - -- `sudo: The "no new privileges" flag is set` - sudo funktioniert nicht -- `/tmp/csf-core-update-status.json: Permission denied` - Schreibrechte-Problem - ---- - -## βœ… Komplette LΓΆsung (Schritt fΓΌr Schritt) - -### πŸ”΄ WICHTIG: Als root/sudo ausfΓΌhren! - -```bash -# Root werden (falls nicht schon root) -sudo -i -``` - ---- - -## 1️⃣ Service-File anpassen - -```bash -nano /etc/systemd/system/csf-core.service -``` - -**Γ„ndere diese Zeilen:** - -**VORHER:** - -```ini -# Security settings -NoNewPrivileges=true -PrivateTmp=true -ProtectSystem=strict -ProtectHome=true -ReadWritePaths=/opt/csf-core -ReadWritePaths=/var/lib/csf-core -ReadWritePaths=/var/log/csf-core -SupplementaryGroups=docker -``` - -**NACHHER:** - -```ini -# Security settings -# NoNewPrivileges disabled to allow sudo for updates -PrivateTmp=true -ProtectSystem=strict -ProtectHome=true -ReadWritePaths=/opt/csf-core -ReadWritePaths=/var/lib/csf-core -ReadWritePaths=/var/log/csf-core -ReadWritePaths=/tmp -SupplementaryGroups=docker -``` - -**Γ„nderungen:** - -- ❌ **Entferne:** `NoNewPrivileges=true` -- βœ… **FΓΌge hinzu:** `ReadWritePaths=/tmp` - -Speichern: `Ctrl+O` β†’ Enter β†’ `Ctrl+X` - ---- - -## 2️⃣ sudoers-Datei KOMPLETT NEU erstellen - -```bash -nano /etc/sudoers.d/csf-core -``` - -**LΓΆsche ALLES und ersetze mit:** - -```sudoers -# Allow csf-core user to run update script without password (with nohup for detachment) -csf-core ALL=(ALL) NOPASSWD: /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup sudo /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup /usr/bin/bash /opt/csf-core/scripts/update.sh* - -# Allow systemctl commands for service management -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl daemon-reload -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl start csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl stop csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl restart csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl status csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl is-active csf-core.service -csf-core ALL=(ALL) NOPASSWD: /usr/bin/systemctl daemon-reload -csf-core ALL=(ALL) NOPASSWD: /usr/bin/systemctl start csf-core.service -csf-core ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop csf-core.service -csf-core ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart csf-core.service -csf-core ALL=(ALL) NOPASSWD: /usr/bin/systemctl status csf-core.service -csf-core ALL=(ALL) NOPASSWD: /usr/bin/systemctl is-active csf-core.service - -# Additional file operations needed during update -csf-core ALL=(ALL) NOPASSWD: /bin/chown -R csf-core\:csf-core /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/cp -rp /opt/csf-core* * -csf-core ALL=(ALL) NOPASSWD: /bin/cp -rp * /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/mv * /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -rf /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -rf /tmp/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -rf /var/tmp/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -f /tmp/csf-core-update-status.json -csf-core ALL=(ALL) NOPASSWD: /bin/mkdir -p * -csf-core ALL=(ALL) NOPASSWD: /bin/tar -xzf * -C /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/chmod +x /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/chmod 644 /tmp/csf-core-update-status.json -csf-core ALL=(ALL) NOPASSWD: /usr/bin/rsync -a * * - -# Allow csf-core to preserve environment and run non-interactively -Defaults:csf-core !requiretty -Defaults:csf-core env_keep += "PATH HOME LANG LC_ALL" -``` - -Speichern: `Ctrl+O` β†’ Enter β†’ `Ctrl+X` - ---- - -## 3️⃣ sudoers validieren und Berechtigungen setzen - -```bash -# WICHTIG: Validieren (muss "parsed OK" ausgeben!) -visudo -c -f /etc/sudoers.d/csf-core -``` - -**Erwartete Ausgabe:** - -``` -/etc/sudoers.d/csf-core: parsed OK -``` - -❌ **Falls NICHT "parsed OK":** Es gibt einen Syntax-Fehler! ZurΓΌck zu Schritt 2 und nochmal prΓΌfen! - -βœ… **Falls "parsed OK":** - -```bash -# Berechtigungen setzen -chmod 0440 /etc/sudoers.d/csf-core -``` - ---- - -## 4️⃣ Update-Skript anpassen (Schreibrechte-Fix) - -```bash -nano /opt/csf-core/scripts/update.sh -``` - -**Suche die Funktion `update_status()` (ca. Zeile 59-72) und ersetze mit:** - -```bash -update_status() { - local status="$1" - local message="$2" - local progress="${3:-0}" - - # Ensure status file directory exists - mkdir -p "$(dirname "$STATUS_FILE")" 2>/dev/null - - # Remove old status file if it exists (to avoid permission issues) - rm -f "$STATUS_FILE" 2>/dev/null - - # Write new status - cat > "$STATUS_FILE" </dev/null || date +%Y-%m-%dT%H:%M:%S)" -} -EOF - - # Make status file readable by everyone (so the backend can read it) - chmod 644 "$STATUS_FILE" 2>/dev/null || true -} -``` - -**Was wurde geΓ€ndert:** - -- βœ… `rm -f "$STATUS_FILE"` - Alte Datei lΓΆschen (Permission-Problem beheben) -- βœ… `chmod 644 "$STATUS_FILE"` - Datei fΓΌr alle lesbar machen - -Speichern: `Ctrl+O` β†’ Enter β†’ `Ctrl+X` - ---- - -## 5️⃣ Alte Status-Datei aufrΓ€umen (falls vorhanden) - -```bash -# Alte Status-Datei lΓΆschen -rm -f /tmp/csf-core-update-status.json - -# Sicherstellen dass /tmp beschreibbar ist -chmod 1777 /tmp -``` - ---- - -## 6️⃣ Service neu laden und starten - -```bash -# Systemd neu laden -systemctl daemon-reload - -# Service neu starten -systemctl restart csf-core.service - -# Status prΓΌfen (muss "active (running)" sein) -systemctl status csf-core.service -``` - -**Erwartete Ausgabe:** - -``` -● csf-core.service - CSF Core Backend and Frontend Service - Loaded: loaded (/etc/systemd/system/csf-core.service; enabled; vendor preset: enabled) - Active: active (running) since ... -``` - ---- - -## 7️⃣ Tests durchfΓΌhren - -### Test 1: sudo ohne Passwort - -```bash -sudo -u csf-core sudo /bin/bash -c "echo 'sudo works!'" -``` - -**Erwartete Ausgabe:** `sudo works!` (OHNE Passwort-Abfrage!) - -### Test 2: Status-Datei Test - -```bash -# Als csf-core User testen -sudo -u csf-core bash -c ' - echo "test" > /tmp/test-status.json - sudo rm -f /tmp/test-status.json - sudo chmod 644 /tmp/test-status.json - echo "Status file operations work!" -' -``` - -### Test 3: Update-Skript Test (Dry-Run) - -```bash -# ACHTUNG: Startet echtes Update! Nur wenn du bereit bist. -# sudo -u csf-core sudo /bin/bash /opt/csf-core/scripts/update.sh 0.4.11 -``` - ---- - -## 8️⃣ Live-Logs beobachten (in separatem Terminal) - -```bash -# In einem zweiten SSH-Terminal -journalctl -u csf-core.service -f -``` - -Jetzt kannst du in der Web-UI das Update triggern und die Logs live sehen! - ---- - -## 🎯 Verifikation - -Nach erfolgreicher DurchfΓΌhrung: - -1. βœ… Service lΓ€uft: `systemctl status csf-core.service` -2. βœ… Web-UI erreichbar -3. βœ… Update ΓΌber Web-UI funktioniert (Settings β†’ Updates β†’ Install Update) -4. βœ… Keine Fehler mehr in Logs - ---- - -## πŸ” Troubleshooting - -### Problem: "parsed OK" schlΓ€gt fehl bei sudoers - -**LΓΆsung:** Syntax-Fehler in `/etc/sudoers.d/csf-core` - -- PrΓΌfe auf fehlende Leerzeichen -- PrΓΌfe auf Tippfehler in Pfaden -- Kopiere nochmal den kompletten Text aus Schritt 2 - -### Problem: Service startet nicht - -**LΓΆsung:** - -```bash -# Logs prΓΌfen -journalctl -u csf-core.service -n 100 --no-pager - -# Konfiguration testen -systemd-analyze verify csf-core.service -``` - -### Problem: "Permission denied" bleibt - -**LΓΆsung:** - -```bash -# Alle alten Status-Dateien lΓΆschen -rm -f /tmp/csf-core-update-status.json -rm -f /var/tmp/csf-core-update-status.json - -# Update-Skript nochmal prΓΌfen (Schritt 4) -cat /opt/csf-core/scripts/update.sh | grep -A 15 "update_status()" -``` - ---- - -## πŸ“‹ Checkliste - -- [ ] Service-File angepasst (NoNewPrivileges entfernt, /tmp hinzugefΓΌgt) -- [ ] sudoers-Datei komplett neu erstellt -- [ ] sudoers validiert (`visudo -c` β†’ "parsed OK") -- [ ] sudoers Berechtigungen gesetzt (0440) -- [ ] Update-Skript angepasst (update_status Funktion) -- [ ] Alte Status-Datei gelΓΆscht -- [ ] systemctl daemon-reload ausgefΓΌhrt -- [ ] Service neu gestartet -- [ ] sudo-Test erfolgreich (ohne Passwort) -- [ ] Service lΓ€uft (systemctl status) -- [ ] Update ΓΌber Web-UI getestet - ---- - -## πŸŽ‰ Fertig! - -Nach diesen Schritten sollte das Update-System vollstΓ€ndig funktionieren. Du kannst jetzt Updates ΓΌber die Web-UI installieren, ohne dass der "no new privileges" oder "Permission denied" Fehler auftritt. - -**Bei Problemen:** Logs prΓΌfen mit `journalctl -u csf-core.service -n 100` diff --git a/REFACTORING_SUMMARY.md b/REFACTORING_SUMMARY.md new file mode 100644 index 0000000..2c9304f --- /dev/null +++ b/REFACTORING_SUMMARY.md @@ -0,0 +1,145 @@ +# πŸŽ‰ CSF-Core Refactoring Complete! + +## βœ… Was wurde umgesetzt: + +### 1. **Multi-Crate Workspace Struktur** + +- Root `Cargo.toml` erstellt mit Workspace-Konfiguration +- Alle Dependencies zentral definiert +- Optimierte Build-Profile + +### 2. **Crates Struktur:** + +#### `crates/shared/` πŸ“¦ + +- **Logger-Modul**: Zentralisierte Logging-FunktionalitΓ€t mit `tracing` +- **DB-Modul**: SeaORM Datenbankverbindung und Migrations-Runner +- Wird von allen anderen Crates verwendet + +#### `crates/entity/` πŸ—ƒοΈ + +- Alle SeaORM Entity-Definitionen +- Kopiert von `backend/entity/` +- Angepasste Cargo.toml mit Workspace-Dependencies + +#### `crates/migration/` πŸ”„ + +- Alle Datenbank-Migrationen +- Kopiert von `backend/migration/` +- Wird von shared verwendet + +#### `crates/control-plane/` πŸŽ›οΈ + +- Gesamter Backend-Code verschoben +- Verwendet `shared::init_logger()` und `shared::establish_connection()` +- Alte `db.rs` entfernt (jetzt in shared) +- Alle Routes, Services und Auth-Module intakt + +#### `crates/agent/` πŸ€– + +- Neue Implementierung mit Test-Logs +- Logger-Integration +- Heartbeat-System als Platzhalter +- Bereit fΓΌr zukΓΌnftige FunktionalitΓ€t + +#### `crates/cli/` πŸ–₯️ + +- Neue Implementierung mit Test-Logs +- Logger-Integration +- Hilfreiche Logging-Ausgaben +- Bereit fΓΌr zukΓΌnftige FunktionalitΓ€t + +### 3. **Docker Compose Development Setup** 🐳 + +#### `docker-compose.dev.yml` + +- **PostgreSQL**: Datenbank auf Port 5432 +- **Control Plane**: Backend API auf Port 8000 mit Hot-Reload +- **Agent**: Background Service mit Docker-Socket-Zugriff +- **CLI**: Als Profil `tools` verfΓΌgbar +- **Frontend**: Development Server auf Port 3000 + +#### Dockerfiles erstellt: + +- `crates/control-plane/Dockerfile.dev` +- `crates/agent/Dockerfile.dev` +- `crates/cli/Dockerfile.dev` + +### 4. **Dokumentation** + +- `DEV_README.md` mit vollstΓ€ndiger Entwicklerdokumentation +- `.env.example` mit allen benΓΆtigten Umgebungsvariablen + +## πŸš€ Wie starten: + +### Lokale Entwicklung: + +```bash +# Einzelne Services +cargo run --bin control-plane +cargo run --bin agent +cargo run --bin csf + +# Mit Hot-Reload +cargo watch -x "run --bin control-plane" +``` + +### Docker Compose: + +```bash +# Alle Services starten +docker-compose -f docker-compose.dev.yml up + +# Mit CLI +docker-compose -f docker-compose.dev.yml --profile tools up +``` + +## πŸ“Š Status: + +- βœ… Workspace kompiliert erfolgreich +- βœ… Alle Dependencies aufgelΓΆst +- βœ… Logger in shared implementiert +- βœ… DB-Verbindungen in shared +- βœ… Control-Plane vollstΓ€ndig migriert +- βœ… Agent mit Test-Logs +- βœ… CLI mit Test-Logs +- βœ… Docker Compose Dev Setup +- βœ… Dokumentation erstellt + +## πŸ” NΓ€chste Schritte: + +1. **Agent implementieren:** + - System-Metriken sammeln + - Zu Control-Plane berichten + - Tasks ausfΓΌhren + +2. **CLI implementieren:** + - Benutzer-Management + - Resource-Management + - System-Konfiguration + +3. **Testing:** + - Integration-Tests fΓΌr das Workspace + - End-to-End Tests mit Docker Compose + +4. **CI/CD:** + - GitHub Actions fΓΌr Workspace-Build + - Multi-Crate Testing + +## πŸ“ Wichtige Hinweise: + +- Alle Crates verwenden Workspace-Dependencies +- Logger wird ΓΌber `shared::init_logger()` initialisiert +- DB-Verbindung ΓΌber `shared::establish_connection()` +- Hot-Reload funktioniert mit `cargo-watch` +- Separate Build-Targets fΓΌr jede Komponente + +## 🎯 Vorteile der neuen Struktur: + +1. **Code-Wiederverwendung**: Shared Logger und DB-Code +2. **Bessere Organisation**: Klare Trennung der Komponenten +3. **Einfacheres Testing**: Jedes Crate ist testbar +4. **Flexibles Deployment**: Jede Komponente einzeln deploybar +5. **Optimierte Builds**: Workspace-weite Dependency-Resolution + +Viel Erfolg mit dem neuen Projekt-Setup! πŸš€ diff --git a/agent/Cargo.lock b/agent/Cargo.lock deleted file mode 100644 index b4b1c2c..0000000 --- a/agent/Cargo.lock +++ /dev/null @@ -1,2732 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - -[[package]] -name = "arraydeque" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" - -[[package]] -name = "asn1-rs" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" -dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "asn1-rs-derive" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "aws-lc-rs" -version = "1.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e84ce723ab67259cfeb9877c6a639ee9eb7a27b28123abd71db7f0d5d0cc9d86" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a442ece363113bd4bd4c8b18977a7798dd4d3c3383f34fb61936960e8f4ad8" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" -dependencies = [ - "serde_core", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "bytes" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" - -[[package]] -name = "cc" -version = "1.2.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "chrono" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-link", -] - -[[package]] -name = "cmake" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" -dependencies = [ - "cc", -] - -[[package]] -name = "config" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" -dependencies = [ - "async-trait", - "convert_case", - "json5", - "nom", - "pathdiff", - "ron", - "rust-ini", - "serde", - "serde_json", - "toml", - "yaml-rust2", -] - -[[package]] -name = "const-random" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" -dependencies = [ - "const-random-macro", -] - -[[package]] -name = "const-random-macro" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" -dependencies = [ - "getrandom 0.2.16", - "once_cell", - "tiny-keccak", -] - -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "crypto-common" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "csf-agent" -version = "0.1.0" -dependencies = [ - "anyhow", - "bytes", - "chrono", - "config", - "hostname", - "http-body-util", - "hyper", - "hyper-util", - "rcgen", - "reqwest", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "sysinfo", - "thiserror", - "time", - "tokio", - "tokio-rustls", - "tokio-util", - "toml", - "tracing", - "tracing-subscriber", - "uuid", - "webpki", -] - -[[package]] -name = "data-encoding" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" - -[[package]] -name = "der-parser" -version = "9.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" -dependencies = [ - "asn1-rs", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - -[[package]] -name = "deranged" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dlv-list" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" -dependencies = [ - "const-random", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "find-msvc-tools" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-task", - "pin-project-lite", - "pin-utils", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", -] - -[[package]] -name = "h2" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "hostname" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd" -dependencies = [ - "cfg-if", - "libc", - "windows-link", -] - -[[package]] -name = "http" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" -dependencies = [ - "bytes", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "system-configuration", - "tokio", - "tower-layer", - "tower-service", - "tracing", - "windows-registry", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core 0.62.2", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" -dependencies = [ - "equivalent", - "hashbrown 0.16.1", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "json5" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" -dependencies = [ - "pest", - "pest_derive", - "serde", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.178" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "mio" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "ntapi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" -dependencies = [ - "winapi", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "oid-registry" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" -dependencies = [ - "asn1-rs", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "openssl" -version = "0.10.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-src" -version = "300.5.4+3.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" -dependencies = [ - "cc", -] - -[[package]] -name = "openssl-sys" -version = "0.9.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" -dependencies = [ - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "ordered-multimap" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" -dependencies = [ - "dlv-list", - "hashbrown 0.14.5", -] - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64 0.22.1", - "serde_core", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pest" -version = "2.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" -dependencies = [ - "memchr", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pest_meta" -version = "2.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" -dependencies = [ - "pest", - "sha2", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "proc-macro2" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "rcgen" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" -dependencies = [ - "pem", - "ring", - "rustls-pki-types", - "time", - "x509-parser", - "yasna", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "reqwest" -version = "0.12.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" -dependencies = [ - "base64 0.22.1", - "bytes", - "encoding_rs", - "futures-core", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-tls", - "hyper-util", - "js-sys", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-native-tls", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "ron" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" -dependencies = [ - "base64 0.21.7", - "bitflags", - "serde", - "serde_derive", -] - -[[package]] -name = "rust-ini" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - -[[package]] -name = "rusticata-macros" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" -dependencies = [ - "nom", -] - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" -dependencies = [ - "aws-lc-rs", - "log", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "schannel" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" -dependencies = [ - "libc", -] - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "sysinfo" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" -dependencies = [ - "core-foundation-sys", - "libc", - "memchr", - "ntapi", - "rayon", - "windows", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "tempfile" -version = "3.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" -dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "time" -version = "0.3.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde_core", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" - -[[package]] -name = "time-macros" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinystr" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tokio" -version = "1.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" -dependencies = [ - "bytes", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "ucd-trie" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" - -[[package]] -name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" -dependencies = [ - "getrandom 0.3.4", - "js-sys", - "serde_core", - "wasm-bindgen", -] - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[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.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" -dependencies = [ - "windows-core 0.57.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" -dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", - "windows-result 0.1.2", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link", - "windows-result 0.4.1", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.57.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" -dependencies = [ - "windows-link", - "windows-result 0.4.1", - "windows-strings", -] - -[[package]] -name = "windows-result" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[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.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.7.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "x509-parser" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" -dependencies = [ - "asn1-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "ring", - "rusticata-macros", - "thiserror", - "time", -] - -[[package]] -name = "yaml-rust2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8902160c4e6f2fb145dbe9d6760a75e3c9522d8bf796ed7047c85919ac7115f8" -dependencies = [ - "arraydeque", - "encoding_rs", - "hashlink", -] - -[[package]] -name = "yasna" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" -dependencies = [ - "time", -] - -[[package]] -name = "yoke" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/agent/Cargo.toml b/agent/Cargo.toml index a36f207..00d8733 100644 --- a/agent/Cargo.toml +++ b/agent/Cargo.toml @@ -1,67 +1,23 @@ [package] -name = "csf-agent" -version = "0.1.0" -edition = "2021" +name = "agent" +version.workspace = true +edition.workspace = true +license.workspace = true -[dependencies] -# Async runtime -tokio = { version = "1", features = ["full"] } - -# System information -sysinfo = "0.32" - -# Serialization -serde = { version = "1", features = ["derive"] } -serde_json = "1" +[[bin]] +name = "agent" +path = "src/main.rs" -# HTTP client for server communication -reqwest = { version = "0.12", features = ["json"] } +[dependencies] +# Internal dependencies +shared = { path = "../control-plane/shared/shared" } -# Configuration -config = "0.14" -toml = "0.8" +# Async runtime +tokio = { workspace = true } # Logging -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter"] } - -# Error handling -anyhow = "1" -thiserror = "1" - -# UUID -uuid = { version = "1", features = ["v4", "serde"] } - -# Time -chrono = { version = "0.4", features = ["serde"] } -time = { version = "0.3", features = ["formatting", "parsing"] } - -# Hostname -hostname = "0.4" - -# TLS/mTLS -rustls = { version = "0.23", features = ["ring"] } -tokio-rustls = "0.26" -rustls-pemfile = "2.0" -rcgen = { version = "0.13", features = ["x509-parser"] } -webpki = "0.22" - -# Async HTTP server -hyper = { version = "1", features = ["full"] } -hyper-util = { version = "0.1", features = ["full"] } -http-body-util = "0.1" - -# Networking -tokio-util = { version = "0.7", features = ["codec"] } -bytes = "1" - -[features] -default = [] -vendored-openssl = ["reqwest/native-tls-vendored"] - -[profile.release] -opt-level = "z" # Optimize for size -lto = true # Link-time optimization -codegen-units = 1 # Better optimization -strip = true # Strip symbols +tracing = { workspace = true } +# Utilities +dotenvy = { workspace = true } +anyhow = { workspace = true } diff --git a/agent/Dockerfile.dev b/agent/Dockerfile.dev new file mode 100644 index 0000000..954ff7c --- /dev/null +++ b/agent/Dockerfile.dev @@ -0,0 +1,35 @@ +# Development Dockerfile for Agent +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && cargo install cargo-watch --version 7.8.0 --locked \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY cli/Cargo.toml ./cli/ +COPY entity/Cargo.toml ./entity/ +COPY control-plane/api-gateway/Cargo.toml ./control-plane/api-gateway/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ + +# Copy service and dependencies +COPY agent/ ./agent/ +COPY shared/ ./shared/ +COPY migration/ ./migration/ + +# Pre-build dependencies (this layer will be cached) +RUN cargo build --bin agent + +# Default command (can be overridden in docker-compose) +CMD ["cargo", "watch", "-x", "run --bin agent"] diff --git a/agent/config.example.toml b/agent/config.example.toml deleted file mode 100644 index 345ab4b..0000000 --- a/agent/config.example.toml +++ /dev/null @@ -1,54 +0,0 @@ -# CSF Agent Configuration -# This file is automatically generated on first run - -# Unique agent identifier (automatically generated) -agent_id = "00000000-0000-0000-0000-000000000000" - -# Agent name (defaults to hostname) -name = "my-agent" - -# Central server URL -server_url = "http://localhost:8000" - -# API key for authentication -api_key = "" - -# Metrics collection interval in seconds -collection_interval = 30 - -# Heartbeat interval in seconds -heartbeat_interval = 60 - -# Tags for this agent -tags = [] - -# P2P (Peer-to-Peer) Configuration -[p2p] -# Enable P2P connections between agents -enabled = false - -# Port to listen for incoming P2P connections -listen_port = 8443 - -# List of peer agents to connect to (format: "host:port") -# Example: peers = ["192.168.1.100:8443", "192.168.1.101:8443"] -peers = [] - -# Path to agent certificate -# Linux default: /etc/csf-agent/certs/agent.crt -# Windows default: C:\ProgramData\csf-agent\certs\agent.crt -cert_path = "" - -# Path to agent private key -# Linux default: /etc/csf-agent/certs/agent.key -# Windows default: C:\ProgramData\csf-agent\certs\agent.key -key_path = "" - -# Path to CA certificate -# Linux default: /etc/csf-agent/certs/ca.crt -# Windows default: C:\ProgramData\csf-agent\certs\ca.crt -ca_cert_path = "" - -# Automatically generate self-signed certificates if not found -# For production, set to false and provide your own certificates -auto_generate_certs = true diff --git a/agent/config.toml b/agent/config.toml deleted file mode 100644 index eb9d0cf..0000000 --- a/agent/config.toml +++ /dev/null @@ -1,16 +0,0 @@ -agent_id = "2e85616c-c24f-4d91-b024-cba384ff3887" -name = "Mac.localdomain" -server_url = "http://localhost:8000" -api_key = "" -collection_interval = 30 -heartbeat_interval = 60 -tags = [] - -[p2p] -enabled = false -listen_port = 8443 -peers = [] -cert_path = "/etc/csf-agent/certs/agent.crt" -key_path = "/etc/csf-agent/certs/agent.key" -ca_cert_path = "/etc/csf-agent/certs/ca.crt" -auto_generate_certs = true diff --git a/agent/src/client.rs b/agent/src/client.rs deleted file mode 100644 index d537d60..0000000 --- a/agent/src/client.rs +++ /dev/null @@ -1,103 +0,0 @@ -use crate::collector::SystemMetrics; -use crate::config::AgentConfig; -use anyhow::Result; -use chrono::{DateTime, Utc}; -use reqwest::Client; -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AgentRegistration { - pub agent_id: Uuid, - pub name: String, - pub hostname: String, - pub os_type: String, - pub os_version: String, - pub architecture: String, - pub agent_version: String, - pub tags: Vec, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RegistrationResponse { - pub success: bool, - pub message: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Heartbeat { - pub agent_id: Uuid, - pub timestamp: DateTime, - pub status: String, -} - -#[derive(Clone)] -pub struct ServerClient { - client: Client, - server_url: String, - api_key: String, -} - -impl ServerClient { - pub fn new(config: &AgentConfig) -> Self { - Self { - client: Client::new(), - server_url: config.server_url.clone(), - api_key: config.api_key.clone(), - } - } - - pub async fn register(&self, registration: &AgentRegistration) -> Result { - let url = format!("{}/api/agents/register", self.server_url); - - let response = self - .client - .post(&url) - .header("X-API-Key", &self.api_key) - .json(registration) - .send() - .await?; - - if response.status().is_success() { - Ok(response.json().await?) - } else { - anyhow::bail!("Registration failed: {}", response.status()) - } - } - - pub async fn send_heartbeat(&self, heartbeat: &Heartbeat) -> Result<()> { - let url = format!("{}/api/agents/heartbeat", self.server_url); - - let response = self - .client - .post(&url) - .header("X-API-Key", &self.api_key) - .json(heartbeat) - .send() - .await?; - - if !response.status().is_success() { - anyhow::bail!("Heartbeat failed: {}", response.status()); - } - - Ok(()) - } - - pub async fn send_metrics(&self, metrics: &SystemMetrics) -> Result<()> { - let url = format!("{}/api/agents/metrics", self.server_url); - - let response = self - .client - .post(&url) - .header("X-API-Key", &self.api_key) - .json(metrics) - .send() - .await?; - - if !response.status().is_success() { - anyhow::bail!("Metrics upload failed: {}", response.status()); - } - - Ok(()) - } -} diff --git a/agent/src/collector.rs b/agent/src/collector.rs deleted file mode 100644 index 3a754ed..0000000 --- a/agent/src/collector.rs +++ /dev/null @@ -1,148 +0,0 @@ -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; -use sysinfo::{Disks, Networks, System}; -use uuid::Uuid; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SystemMetrics { - pub agent_id: Uuid, - pub timestamp: DateTime, - - // CPU - pub cpu_model: String, - pub cpu_cores: u32, - pub cpu_threads: u32, - pub cpu_usage_percent: f32, - - // Memory - pub memory_total_bytes: u64, - pub memory_used_bytes: u64, - pub memory_usage_percent: f32, - - // Disk - pub disk_total_bytes: u64, - pub disk_used_bytes: u64, - pub disk_usage_percent: f32, - - // Network - pub network_rx_bytes: u64, - pub network_tx_bytes: u64, - - // System - pub os_name: String, - pub os_version: String, - pub kernel_version: String, - pub hostname: String, - pub uptime_seconds: u64, -} - -pub struct MetricsCollector { - system: System, - networks: Networks, - disks: Disks, -} - -impl MetricsCollector { - pub fn new() -> Self { - Self { - system: System::new_all(), - networks: Networks::new_with_refreshed_list(), - disks: Disks::new_with_refreshed_list(), - } - } - - pub fn collect(&mut self, agent_id: Uuid) -> SystemMetrics { - // Refresh all data - self.system.refresh_all(); - self.networks.refresh(); - self.disks.refresh(); - - // CPU info - let cpu_model = self - .system - .cpus() - .first() - .map(|cpu| cpu.brand().to_string()) - .unwrap_or_else(|| "Unknown".to_string()); - - let cpu_cores = self.system.physical_core_count().unwrap_or(0) as u32; - let cpu_threads = self.system.cpus().len() as u32; - - let cpu_usage_percent = if !self.system.cpus().is_empty() { - let total: f32 = self.system.cpus().iter().map(|cpu| cpu.cpu_usage()).sum(); - total / self.system.cpus().len() as f32 - } else { - 0.0 - }; - - // Memory - let memory_total_bytes = self.system.total_memory(); - let memory_used_bytes = self.system.used_memory(); - let memory_usage_percent = if memory_total_bytes > 0 { - (memory_used_bytes as f32 / memory_total_bytes as f32) * 100.0 - } else { - 0.0 - }; - - // Disk - let (disk_total_bytes, disk_used_bytes) = - self.disks.iter().fold((0u64, 0u64), |(total, used), disk| { - ( - total + disk.total_space(), - used + (disk.total_space() - disk.available_space()), - ) - }); - - let disk_usage_percent = if disk_total_bytes > 0 { - (disk_used_bytes as f32 / disk_total_bytes as f32) * 100.0 - } else { - 0.0 - }; - - // Network - let (network_rx_bytes, network_tx_bytes) = - self.networks - .iter() - .fold((0u64, 0u64), |(rx, tx), (_name, network)| { - ( - rx + network.total_received(), - tx + network.total_transmitted(), - ) - }); - - // System info - let hostname = System::host_name().unwrap_or_else(|| "unknown".to_string()); - let os_name = System::name().unwrap_or_else(|| "Unknown".to_string()); - let os_version = System::os_version().unwrap_or_else(|| "Unknown".to_string()); - let kernel_version = System::kernel_version().unwrap_or_else(|| "Unknown".to_string()); - let uptime_seconds = System::uptime(); - - SystemMetrics { - agent_id, - timestamp: Utc::now(), - cpu_model, - cpu_cores, - cpu_threads, - cpu_usage_percent, - memory_total_bytes, - memory_used_bytes, - memory_usage_percent, - disk_total_bytes, - disk_used_bytes, - disk_usage_percent, - network_rx_bytes, - network_tx_bytes, - os_name, - os_version, - kernel_version, - hostname, - uptime_seconds, - } - } -} - -impl Default for MetricsCollector { - fn default() -> Self { - Self::new() - } -} diff --git a/agent/src/config.rs b/agent/src/config.rs deleted file mode 100644 index a969039..0000000 --- a/agent/src/config.rs +++ /dev/null @@ -1,168 +0,0 @@ -use serde::{Deserialize, Serialize}; -use uuid::Uuid; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AgentConfig { - /// Unique agent ID (generated on first run) - pub agent_id: Uuid, - - /// Name of this agent - pub name: String, - - /// URL of the central server - pub server_url: String, - - /// API key for authentication (optional if only P2P is used) - pub api_key: String, - - /// Skip backend connection if only P2P mode is needed - pub p2p_only_mode: bool, - - /// How often to collect metrics (seconds) - pub collection_interval: u64, - - /// How often to send heartbeat (seconds) - pub heartbeat_interval: u64, - - /// Tags for this agent - pub tags: Vec, - - /// P2P connection settings - pub p2p: P2PConfig, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct P2PConfig { - /// Enable P2P connections between agents - pub enabled: bool, - - /// Port to listen for P2P connections - pub listen_port: u16, - - /// List of peer agents to connect to (host:port) - pub peers: Vec, - - /// mTLS certificate path - pub cert_path: String, - - /// mTLS private key path - pub key_path: String, - - /// CA certificate path for verifying peers - pub ca_cert_path: String, - - /// Auto-generate self-signed certificates if not found - pub auto_generate_certs: bool, -} - -impl Default for P2PConfig { - fn default() -> Self { - Self { - enabled: false, - listen_port: 8443, - peers: vec![], - cert_path: Self::default_cert_path().to_string_lossy().to_string(), - key_path: Self::default_key_path().to_string_lossy().to_string(), - ca_cert_path: Self::default_ca_cert_path().to_string_lossy().to_string(), - auto_generate_certs: true, - } - } -} - -impl P2PConfig { - fn default_cert_path() -> std::path::PathBuf { - if cfg!(target_os = "windows") { - std::path::PathBuf::from("C:\\ProgramData\\csf-agent\\certs\\agent.crt") - } else { - std::path::PathBuf::from("/etc/csf-agent/certs/agent.crt") - } - } - - fn default_key_path() -> std::path::PathBuf { - if cfg!(target_os = "windows") { - std::path::PathBuf::from("C:\\ProgramData\\csf-agent\\certs\\agent.key") - } else { - std::path::PathBuf::from("/etc/csf-agent/certs/agent.key") - } - } - - fn default_ca_cert_path() -> std::path::PathBuf { - if cfg!(target_os = "windows") { - std::path::PathBuf::from("C:\\ProgramData\\csf-agent\\certs\\ca.crt") - } else { - std::path::PathBuf::from("/etc/csf-agent/certs/ca.crt") - } - } -} - -impl Default for AgentConfig { - fn default() -> Self { - Self { - agent_id: Uuid::new_v4(), - name: hostname::get() - .ok() - .and_then(|h| h.into_string().ok()) - .unwrap_or_else(|| "unknown".to_string()), - server_url: "http://localhost:8000".to_string(), - api_key: String::new(), - p2p_only_mode: false, - collection_interval: 30, - heartbeat_interval: 60, - tags: vec![], - p2p: P2PConfig::default(), - } - } -} - -impl AgentConfig { - pub fn load() -> anyhow::Result { - // Try to load from config file, otherwise use defaults - // Check local directory first (for testing), then system path - let local_config = std::path::PathBuf::from("config.toml"); - let system_config = Self::config_path(); - - let config_path = if local_config.exists() { - local_config - } else { - system_config - }; - - if config_path.exists() { - let content = std::fs::read_to_string(&config_path)?; - Ok(toml::from_str(&content)?) - } else { - Ok(Self::default()) - } - } - - pub fn save(&self) -> anyhow::Result<()> { - // Try local directory first (for testing), then system path - let local_config = std::path::PathBuf::from("config.toml"); - let system_config = Self::config_path(); - - // If we can write to local directory, use that - let config_path = if local_config.exists() || std::env::current_dir().is_ok() { - local_config - } else { - system_config - }; - - // Create parent directory if it doesn't exist - if let Some(parent) = config_path.parent() { - std::fs::create_dir_all(parent).ok(); - } - - let content = toml::to_string_pretty(self)?; - std::fs::write(&config_path, content)?; - - Ok(()) - } - - fn config_path() -> std::path::PathBuf { - if cfg!(target_os = "windows") { - std::path::PathBuf::from("C:\\ProgramData\\csf-agent\\config.toml") - } else { - std::path::PathBuf::from("/etc/csf-agent/config.toml") - } - } -} diff --git a/agent/src/connect/certs.rs b/agent/src/connect/certs.rs deleted file mode 100644 index aa4a78b..0000000 --- a/agent/src/connect/certs.rs +++ /dev/null @@ -1,217 +0,0 @@ -use anyhow::{Context, Result}; -use rcgen::{ - BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa, KeyPair, KeyUsagePurpose, -}; -use std::fs; -use std::path::Path; -use time::{Duration, OffsetDateTime}; - -/// Generates a self-signed CA certificate -pub fn generate_ca_cert(common_name: &str, output_dir: &Path) -> Result<()> { - let mut params = CertificateParams::default(); - params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained); - - let mut dn = DistinguishedName::new(); - dn.push(DnType::CommonName, common_name); - dn.push(DnType::OrganizationName, "CSF Agent Network"); - dn.push(DnType::CountryName, "US"); - params.distinguished_name = dn; - - // Set validity period (10 years) - params.not_before = OffsetDateTime::now_utc(); - params.not_after = OffsetDateTime::now_utc() + Duration::days(3650); - - // Key usage for CA - params.key_usages = vec![ - KeyUsagePurpose::DigitalSignature, - KeyUsagePurpose::KeyCertSign, - KeyUsagePurpose::CrlSign, - ]; - - let key_pair = KeyPair::generate()?; - let cert = params.self_signed(&key_pair)?; - - // Create output directory - fs::create_dir_all(output_dir).context("Failed to create certificate directory")?; - - // Save CA certificate - let ca_cert_path = output_dir.join("ca.crt"); - fs::write(&ca_cert_path, cert.pem()).context("Failed to write CA certificate")?; - - // Save CA private key - let ca_key_path = output_dir.join("ca.key"); - fs::write(&ca_key_path, key_pair.serialize_pem()).context("Failed to write CA private key")?; - - // Set restrictive permissions on private key (Unix only) - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - let mut perms = fs::metadata(&ca_key_path)?.permissions(); - perms.set_mode(0o600); - fs::set_permissions(&ca_key_path, perms)?; - } - - tracing::info!("Generated CA certificate at {:?}", ca_cert_path); - Ok(()) -} - -/// Generates an agent certificate signed by the CA -pub fn generate_agent_cert( - agent_name: &str, - ca_cert_path: &Path, - ca_key_path: &Path, - output_dir: &Path, -) -> Result<()> { - // Load CA certificate and key - let ca_cert_pem = fs::read_to_string(ca_cert_path).context("Failed to read CA certificate")?; - let ca_key_pem = fs::read_to_string(ca_key_path).context("Failed to read CA private key")?; - - let ca_key_pair = KeyPair::from_pem(&ca_key_pem).context("Failed to parse CA private key")?; - let ca_cert_params = CertificateParams::from_ca_cert_pem(&ca_cert_pem) - .context("Failed to parse CA certificate")?; - let ca_cert = ca_cert_params.self_signed(&ca_key_pair)?; - - // Create agent certificate parameters - let mut params = CertificateParams::default(); - - let mut dn = DistinguishedName::new(); - dn.push(DnType::CommonName, agent_name); - dn.push(DnType::OrganizationName, "CSF Agent Network"); - params.distinguished_name = dn; - - // Set validity period (1 year) - params.not_before = OffsetDateTime::now_utc(); - params.not_after = OffsetDateTime::now_utc() + Duration::days(365); - - // Key usage for agent certificates - params.key_usages = vec![ - KeyUsagePurpose::DigitalSignature, - KeyUsagePurpose::KeyEncipherment, - ]; - - // Extended key usage for server and client auth - params.extended_key_usages = vec![ - rcgen::ExtendedKeyUsagePurpose::ServerAuth, - rcgen::ExtendedKeyUsagePurpose::ClientAuth, - ]; - - // Add SubjectAlternativeNames for localhost and common IPs - params.subject_alt_names = vec![ - rcgen::SanType::DnsName("localhost".try_into().unwrap()), - rcgen::SanType::IpAddress(std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1))), - rcgen::SanType::IpAddress(std::net::IpAddr::V6(std::net::Ipv6Addr::new( - 0, 0, 0, 0, 0, 0, 0, 1, - ))), - ]; - - // Generate agent key pair - let agent_key_pair = KeyPair::generate()?; - - // Sign agent certificate with CA - let agent_cert = params.signed_by(&agent_key_pair, &ca_cert, &ca_key_pair)?; - - // Create output directory - fs::create_dir_all(output_dir).context("Failed to create certificate directory")?; - - // Save agent certificate - let agent_cert_path = output_dir.join("agent.crt"); - fs::write(&agent_cert_path, agent_cert.pem()).context("Failed to write agent certificate")?; - - // Save agent private key - let agent_key_path = output_dir.join("agent.key"); - fs::write(&agent_key_path, agent_key_pair.serialize_pem()) - .context("Failed to write agent private key")?; - - // Set restrictive permissions on private key (Unix only) - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - let mut perms = fs::metadata(&agent_key_path)?.permissions(); - perms.set_mode(0o600); - fs::set_permissions(&agent_key_path, perms)?; - } - - tracing::info!("Generated agent certificate at {:?}", agent_cert_path); - Ok(()) -} - -/// Ensures certificates exist, generates them if needed -pub fn ensure_certificates(agent_name: &str, cert_dir: &Path, auto_generate: bool) -> Result<()> { - let ca_cert_path = cert_dir.join("ca.crt"); - let ca_key_path = cert_dir.join("ca.key"); - let agent_cert_path = cert_dir.join("agent.crt"); - let agent_key_path = cert_dir.join("agent.key"); - - // Check if certificates already exist - let ca_exists = ca_cert_path.exists() && ca_key_path.exists(); - let agent_exists = agent_cert_path.exists() && agent_key_path.exists(); - - if ca_exists && agent_exists { - tracing::info!("Certificates already exist, skipping generation"); - return Ok(()); - } - - if !auto_generate { - anyhow::bail!( - "Certificates not found and auto-generation is disabled. \ - Please provide certificates at {:?}", - cert_dir - ); - } - - tracing::info!("Generating certificates..."); - - // Generate CA if it doesn't exist - if !ca_exists { - let ca_common_name = format!("CSF-Agent-CA-{}", uuid::Uuid::new_v4()); - generate_ca_cert(&ca_common_name, cert_dir)?; - } - - // Generate agent certificate if it doesn't exist - if !agent_exists { - generate_agent_cert(agent_name, &ca_cert_path, &ca_key_path, cert_dir)?; - } - - Ok(()) -} - -/// Loads certificates for mTLS -pub fn load_certs(path: &Path) -> Result>> { - let cert_file = - fs::File::open(path).context(format!("Failed to open certificate file: {:?}", path))?; - let mut reader = std::io::BufReader::new(cert_file); - - rustls_pemfile::certs(&mut reader) - .collect::, _>>() - .context("Failed to parse certificates") -} - -/// Loads private key -pub fn load_private_key(path: &Path) -> Result> { - let key_file = - fs::File::open(path).context(format!("Failed to open private key file: {:?}", path))?; - let mut reader = std::io::BufReader::new(key_file); - - // Try to read as PKCS8 first - if let Some(key) = rustls_pemfile::pkcs8_private_keys(&mut reader) - .next() - .transpose() - .context("Failed to parse PKCS8 private key")? - { - return Ok(rustls::pki_types::PrivateKeyDer::Pkcs8(key)); - } - - // Reset reader and try RSA - let key_file = fs::File::open(path)?; - let mut reader = std::io::BufReader::new(key_file); - - if let Some(key) = rustls_pemfile::rsa_private_keys(&mut reader) - .next() - .transpose() - .context("Failed to parse RSA private key")? - { - return Ok(rustls::pki_types::PrivateKeyDer::Pkcs1(key)); - } - - anyhow::bail!("No valid private key found in {:?}", path) -} diff --git a/agent/src/connect/connector.rs b/agent/src/connect/connector.rs deleted file mode 100644 index bb785b8..0000000 --- a/agent/src/connect/connector.rs +++ /dev/null @@ -1,432 +0,0 @@ -use anyhow::{Context, Result}; -use chrono::{DateTime, Utc}; -use rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName}; -use rustls::RootCertStore; -use serde::{Deserialize, Serialize}; -use std::net::SocketAddr; -use std::path::Path; -use std::sync::Arc; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::{TcpListener, TcpStream}; -use tokio_rustls::{TlsAcceptor, TlsConnector}; -use uuid::Uuid; - -use super::certs; - -/// Message types for P2P communication -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "type")] -pub enum P2PMessage { - /// Handshake message to establish connection - Handshake { - agent_id: Uuid, - agent_name: String, - timestamp: DateTime, - }, - /// Heartbeat to maintain connection - Heartbeat { - agent_id: Uuid, - timestamp: DateTime, - }, - /// Share metrics with peer - MetricsShare { - agent_id: Uuid, - timestamp: DateTime, - metrics: serde_json::Value, - }, - /// Request metrics from peer - MetricsRequest { - agent_id: Uuid, - timestamp: DateTime, - }, - /// Response to a request - Response { - success: bool, - message: String, - data: Option, - }, -} - -/// mTLS P2P Connector for agent-to-agent communication -#[derive(Clone)] -pub struct P2PConnector { - agent_id: Uuid, - agent_name: String, - listen_addr: SocketAddr, - tls_acceptor: TlsAcceptor, - tls_connector: TlsConnector, -} - -impl P2PConnector { - /// Creates a new P2P connector with mTLS configuration - pub fn new( - agent_id: Uuid, - agent_name: String, - listen_port: u16, - cert_path: &Path, - key_path: &Path, - ca_cert_path: &Path, - ) -> Result { - // Load certificates - let certs = certs::load_certs(cert_path).context("Failed to load agent certificate")?; - let key = certs::load_private_key(key_path).context("Failed to load agent private key")?; - let ca_certs = certs::load_certs(ca_cert_path).context("Failed to load CA certificate")?; - - // Build server config (for accepting connections) - let server_config = Self::build_server_config(certs.clone(), key.clone_key(), &ca_certs)?; - let tls_acceptor = TlsAcceptor::from(Arc::new(server_config)); - - // Build client config (for initiating connections) - let client_config = Self::build_client_config(certs, key, &ca_certs)?; - let tls_connector = TlsConnector::from(Arc::new(client_config)); - - let listen_addr = SocketAddr::from(([0, 0, 0, 0], listen_port)); - - Ok(Self { - agent_id, - agent_name, - listen_addr, - tls_acceptor, - tls_connector, - }) - } - - /// Build server TLS config for accepting connections - fn build_server_config( - certs: Vec>, - key: PrivateKeyDer<'static>, - ca_certs: &[CertificateDer<'static>], - ) -> Result { - // Create root cert store for client verification - let mut root_store = RootCertStore::empty(); - for cert in ca_certs { - root_store - .add(cert.clone()) - .context("Failed to add CA certificate to root store")?; - } - - // Create verifier that requires client certificates - let client_verifier = rustls::server::WebPkiClientVerifier::builder(Arc::new(root_store)) - .build() - .context("Failed to build client verifier")?; - - let config = rustls::ServerConfig::builder() - .with_client_cert_verifier(client_verifier) - .with_single_cert(certs, key) - .context("Failed to build server config")?; - - Ok(config) - } - - /// Build client TLS config for initiating connections - fn build_client_config( - certs: Vec>, - key: PrivateKeyDer<'static>, - ca_certs: &[CertificateDer<'static>], - ) -> Result { - // Create root cert store for server verification - let mut root_store = RootCertStore::empty(); - for cert in ca_certs { - root_store - .add(cert.clone()) - .context("Failed to add CA certificate to root store")?; - } - - let config = rustls::ClientConfig::builder() - .with_root_certificates(root_store) - .with_client_auth_cert(certs, key) - .context("Failed to build client config")?; - - Ok(config) - } - - /// Start listening for incoming P2P connections - pub async fn start_server(&self) -> Result<()> { - let listener = TcpListener::bind(self.listen_addr) - .await - .context(format!("Failed to bind to {}", self.listen_addr))?; - - tracing::info!("P2P server listening on {}", self.listen_addr); - - loop { - match listener.accept().await { - Ok((stream, peer_addr)) => { - tracing::info!("Accepted connection from {}", peer_addr); - let acceptor = self.tls_acceptor.clone(); - let agent_id = self.agent_id; - let agent_name = self.agent_name.clone(); - - tokio::spawn(async move { - if let Err(e) = Self::handle_connection( - stream, acceptor, agent_id, agent_name, peer_addr, - ) - .await - { - tracing::error!("Error handling connection from {}: {}", peer_addr, e); - } - }); - } - Err(e) => { - tracing::error!("Error accepting connection: {}", e); - } - } - } - } - - /// Handle an incoming connection - async fn handle_connection( - stream: TcpStream, - acceptor: TlsAcceptor, - agent_id: Uuid, - agent_name: String, - peer_addr: SocketAddr, - ) -> Result<()> { - // Perform TLS handshake - let mut tls_stream = match acceptor.accept(stream).await { - Ok(s) => s, - Err(e) => { - anyhow::bail!("TLS handshake failed: {:?}", e); - } - }; - - tracing::info!("TLS handshake completed with {}", peer_addr); - - // Send handshake message - let handshake = P2PMessage::Handshake { - agent_id, - agent_name: agent_name.clone(), - timestamp: Utc::now(), - }; - Self::send_message(&mut tls_stream, &handshake).await?; - - // Receive handshake response - let response = Self::receive_message(&mut tls_stream).await?; - match response { - P2PMessage::Handshake { - agent_id: peer_id, - agent_name: peer_name, - .. - } => { - tracing::info!("Connected to peer: {} ({})", peer_name, peer_id); - } - _ => { - anyhow::bail!("Expected handshake message, got: {:?}", response); - } - } - - // Keep connection alive and handle messages - loop { - match Self::receive_message(&mut tls_stream).await { - Ok(message) => { - tracing::debug!("Received message: {:?}", message); - - // Handle different message types - match message { - P2PMessage::Heartbeat { - agent_id: peer_id, .. - } => { - tracing::debug!("Heartbeat from {}", peer_id); - - // Send heartbeat response - let response = P2PMessage::Response { - success: true, - message: "Heartbeat received".to_string(), - data: None, - }; - Self::send_message(&mut tls_stream, &response).await?; - } - P2PMessage::MetricsRequest { - agent_id: peer_id, .. - } => { - tracing::debug!("Metrics request from {}", peer_id); - - // TODO: Get current metrics and send them - let response = P2PMessage::Response { - success: true, - message: "Metrics data".to_string(), - data: Some(serde_json::json!({"status": "ok"})), - }; - Self::send_message(&mut tls_stream, &response).await?; - } - P2PMessage::MetricsShare { - agent_id: peer_id, - metrics, - .. - } => { - tracing::info!("Received metrics from {}: {:?}", peer_id, metrics); - } - _ => { - tracing::warn!("Unhandled message type: {:?}", message); - } - } - } - Err(e) => { - tracing::info!("Connection closed: {}", e); - break; - } - } - } - - Ok(()) - } - - /// Connect to a peer agent - pub async fn connect_to_peer( - &self, - peer_addr: &str, - ) -> Result> { - // Parse address - let addr: SocketAddr = peer_addr - .parse() - .context(format!("Invalid peer address: {}", peer_addr))?; - - tracing::info!("Connecting to peer at {}", addr); - - // Connect to peer - let stream = TcpStream::connect(addr) - .await - .context(format!("Failed to connect to {}", addr))?; - - // Extract hostname for SNI - let hostname = addr.ip().to_string(); - let server_name = ServerName::try_from(hostname) - .context("Invalid hostname")? - .to_owned(); - - // Perform TLS handshake - let mut tls_stream = match self.tls_connector.connect(server_name, stream).await { - Ok(s) => s, - Err(e) => { - anyhow::bail!("TLS handshake failed: {:?}", e); - } - }; - - tracing::info!("TLS handshake completed with {}", addr); - - // Receive handshake from server - let handshake = Self::receive_message(&mut tls_stream).await?; - match handshake { - P2PMessage::Handshake { - agent_id: peer_id, - agent_name: peer_name, - .. - } => { - tracing::info!("Connected to peer: {} ({})", peer_name, peer_id); - } - _ => { - anyhow::bail!("Expected handshake message"); - } - } - - // Send our handshake - let handshake = P2PMessage::Handshake { - agent_id: self.agent_id, - agent_name: self.agent_name.clone(), - timestamp: Utc::now(), - }; - Self::send_message(&mut tls_stream, &handshake).await?; - - Ok(tls_stream) - } - - /// Send a message over any TLS stream - async fn send_message(stream: &mut S, message: &P2PMessage) -> Result<()> - where - S: AsyncReadExt + AsyncWriteExt + Unpin, - { - let json = serde_json::to_string(message)?; - let len = json.len() as u32; - - // Send length prefix (4 bytes) - stream.write_all(&len.to_be_bytes()).await?; - // Send JSON data - stream.write_all(json.as_bytes()).await?; - stream.flush().await?; - - Ok(()) - } - - /// Receive a message from any TLS stream - async fn receive_message(stream: &mut S) -> Result - where - S: AsyncReadExt + AsyncWriteExt + Unpin, - { - // Read length prefix (4 bytes) - let mut len_bytes = [0u8; 4]; - stream.read_exact(&mut len_bytes).await?; - let len = u32::from_be_bytes(len_bytes) as usize; - - // Read JSON data - let mut buffer = vec![0u8; len]; - stream.read_exact(&mut buffer).await?; - - let message: P2PMessage = serde_json::from_slice(&buffer)?; - Ok(message) - } - - /// Send a heartbeat to a peer - pub async fn send_heartbeat(&self, stream: &mut S) -> Result<()> - where - S: AsyncReadExt + AsyncWriteExt + Unpin, - { - let heartbeat = P2PMessage::Heartbeat { - agent_id: self.agent_id, - timestamp: Utc::now(), - }; - - Self::send_message(stream, &heartbeat).await?; - - // Wait for response - let response = Self::receive_message(stream).await?; - match response { - P2PMessage::Response { - success, message, .. - } => { - if success { - tracing::debug!("Heartbeat acknowledged: {}", message); - } else { - anyhow::bail!("Heartbeat failed: {}", message); - } - } - _ => { - anyhow::bail!("Unexpected response to heartbeat"); - } - } - - Ok(()) - } - - /// Request metrics from a peer - #[allow(dead_code)] - pub async fn request_metrics(&self, stream: &mut S) -> Result - where - S: AsyncReadExt + AsyncWriteExt + Unpin, - { - let request = P2PMessage::MetricsRequest { - agent_id: self.agent_id, - timestamp: Utc::now(), - }; - - Self::send_message(stream, &request).await?; - - // Wait for response - let response = Self::receive_message(stream).await?; - match response { - P2PMessage::Response { - success, - data, - message, - .. - } => { - if success { - Ok(data.unwrap_or(serde_json::json!({}))) - } else { - anyhow::bail!("Metrics request failed: {}", message); - } - } - _ => { - anyhow::bail!("Unexpected response to metrics request"); - } - } - } -} diff --git a/agent/src/connect/mod.rs b/agent/src/connect/mod.rs deleted file mode 100644 index b21e81b..0000000 --- a/agent/src/connect/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod certs; -pub mod connector; - -pub use certs::ensure_certificates; -pub use connector::P2PConnector; diff --git a/agent/src/main.rs b/agent/src/main.rs index 5aea219..0866b72 100644 --- a/agent/src/main.rs +++ b/agent/src/main.rs @@ -1,229 +1,29 @@ -mod client; -mod collector; -mod config; -mod connect; - use anyhow::Result; -use chrono::Utc; -use client::{AgentRegistration, Heartbeat, ServerClient}; -use collector::MetricsCollector; -use config::AgentConfig; -use connect::{ensure_certificates, P2PConnector}; -use std::time::Duration; -use tracing::{error, info, warn}; #[tokio::main] async fn main() -> Result<()> { - // Initialize rustls crypto provider - let _ = rustls::crypto::ring::default_provider().install_default(); - - // Initialize logging - tracing_subscriber::fmt() - .with_env_filter( - tracing_subscriber::EnvFilter::try_from_default_env() - .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), - ) - .init(); - - info!("πŸš€ CSF Agent starting..."); - - // Load or create configuration - let config = AgentConfig::load().unwrap_or_else(|e| { - warn!("Failed to load config: {}. Using defaults.", e); - AgentConfig::default() - }); - - // Save config if it's new - if config.api_key.is_empty() { - warn!("⚠️ No API key configured. Agent will not be able to connect to server."); - warn!(" Please configure the agent by editing: /etc/csf-agent/config.toml"); - config.save()?; - return Ok(()); - } - - config.save()?; - info!("πŸ“ Configuration loaded"); - info!(" Agent ID: {}", config.agent_id); - info!(" Name: {}", config.name); - if !config.p2p_only_mode { - info!(" Server: {}", config.server_url); - } else { - info!(" Mode: P2P Only (no backend connection)"); - } - - // Initialize P2P if enabled - let p2p_connector = if config.p2p.enabled { - info!("πŸ” P2P connections enabled"); - - // Get certificate directory - let cert_dir = if let Some(parent) = std::path::Path::new(&config.p2p.cert_path).parent() { - parent.to_path_buf() - } else { - std::path::PathBuf::from(if cfg!(target_os = "windows") { - "C:\\ProgramData\\csf-agent\\certs" - } else { - "/etc/csf-agent/certs" - }) - }; - - // Ensure certificates exist - match ensure_certificates(&config.name, &cert_dir, config.p2p.auto_generate_certs) { - Ok(_) => info!("βœ… Certificates ready"), - Err(e) => { - error!("❌ Failed to setup certificates: {}", e); - return Err(e); - } - } - - // Create P2P connector - match P2PConnector::new( - config.agent_id, - config.name.clone(), - config.p2p.listen_port, - std::path::Path::new(&config.p2p.cert_path), - std::path::Path::new(&config.p2p.key_path), - std::path::Path::new(&config.p2p.ca_cert_path), - ) { - Ok(connector) => { - info!( - "βœ… P2P connector initialized on port {}", - config.p2p.listen_port - ); - Some(connector) - } - Err(e) => { - error!("❌ Failed to create P2P connector: {}", e); - return Err(e); - } - } - } else { - info!("ℹ️ P2P connections disabled"); - None - }; - - // Start P2P server if enabled - if let Some(ref connector) = p2p_connector { - let connector_clone = connector.clone(); - tokio::spawn(async move { - if let Err(e) = connector_clone.start_server().await { - error!("❌ P2P server error: {}", e); - } - }); - - // Connect to configured peers - for peer in &config.p2p.peers { - let connector_clone = connector.clone(); - let peer_addr = peer.clone(); - tokio::spawn(async move { - info!("πŸ”— Connecting to peer: {}", peer_addr); - match connector_clone.connect_to_peer(&peer_addr).await { - Ok(mut stream) => { - info!("βœ… Connected to peer: {}", peer_addr); - - // Keep connection alive with heartbeats - let mut interval = tokio::time::interval(Duration::from_secs(30)); - loop { - interval.tick().await; - - if let Err(e) = connector_clone.send_heartbeat(&mut stream).await { - error!( - "❌ Heartbeat to {} failed: {}. Reconnecting...", - peer_addr, e - ); - break; - } - } - } - Err(e) => { - error!("❌ Failed to connect to peer {}: {}", peer_addr, e); - } - } - }); - } - } - - // Initialize components - let client = ServerClient::new(&config); - let mut collector = MetricsCollector::new(); - - // Register with server (skip if P2P only mode) - if !config.p2p_only_mode { - info!("πŸ“‘ Registering with server..."); - let registration = AgentRegistration { - agent_id: config.agent_id, - name: config.name.clone(), - hostname: hostname::get() - .ok() - .and_then(|h| h.into_string().ok()) - .unwrap_or_else(|| "unknown".to_string()), - os_type: std::env::consts::OS.to_string(), - os_version: sysinfo::System::os_version().unwrap_or_else(|| "Unknown".to_string()), - architecture: std::env::consts::ARCH.to_string(), - agent_version: env!("CARGO_PKG_VERSION").to_string(), - tags: config.tags.clone(), - }; - - match client.register(®istration).await { - Ok(response) => { - info!("βœ… Registration successful: {}", response.message); - } - Err(e) => { - error!("❌ Registration failed: {}", e); - warn!(" Continuing anyway, will retry on next heartbeat..."); - } - } - - // Spawn heartbeat task - let heartbeat_client = client.clone(); - let heartbeat_agent_id = config.agent_id; - let heartbeat_interval = config.heartbeat_interval; - tokio::spawn(async move { - let mut interval = tokio::time::interval(Duration::from_secs(heartbeat_interval)); - loop { - interval.tick().await; - - let heartbeat = Heartbeat { - agent_id: heartbeat_agent_id, - timestamp: Utc::now(), - status: "online".to_string(), - }; - - if let Err(e) = heartbeat_client.send_heartbeat(&heartbeat).await { - error!("Failed to send heartbeat: {}", e); - } else { - info!("πŸ’“ Heartbeat sent"); - } - } - }); - } else { - info!("ℹ️ Backend connection disabled (P2P only mode)"); - } - - // Main metrics collection loop - info!("πŸ“Š Starting metrics collection..."); - let mut interval = tokio::time::interval(Duration::from_secs(config.collection_interval)); - + // Load .env file if it exists + dotenvy::dotenv().ok(); + + // Initialize shared logger + shared::init_logger(); + + tracing::info!("πŸ€– CSF Agent starting..."); + tracing::info!("Version: {}", env!("CARGO_PKG_VERSION")); + + // TODO: Implement agent functionality + // Agent will: + // - Monitor system resources + // - Report metrics to control plane + // - Execute tasks from control plane + // - Manage local Docker containers + + tracing::warn!("⚠️ Agent functionality not yet implemented"); + tracing::info!("βœ… Test log: Agent initialized successfully"); + + // Keep the agent running loop { - interval.tick().await; - - // Collect metrics - let metrics = collector.collect(config.agent_id); - - info!( - "πŸ“ˆ Metrics - CPU: {:.1}% | RAM: {:.1}% | Disk: {:.1}%", - metrics.cpu_usage_percent, metrics.memory_usage_percent, metrics.disk_usage_percent - ); - - // Send to server (skip if P2P only mode) - if !config.p2p_only_mode { - match client.send_metrics(&metrics).await { - Ok(_) => { - info!("βœ… Metrics sent to server"); - } - Err(e) => { - error!("❌ Failed to send metrics: {}", e); - } - } - } + tokio::time::sleep(tokio::time::Duration::from_secs(30)).await; + tracing::debug!("Agent heartbeat..."); } } diff --git a/agent/test-p2p.sh b/agent/test-p2p.sh deleted file mode 100755 index 7cf4b94..0000000 --- a/agent/test-p2p.sh +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/bash - -echo "πŸ§ͺ P2P mTLS Test" -echo "=================" - -# Cleanup -echo "🧹 Cleanup old test files..." -rm -rf test-agent1 test-agent2 -mkdir -p test-agent1/certs test-agent2/certs - -# Build -echo "πŸ”¨ Building agent..." -cargo build --release -if [ $? -ne 0 ]; then - echo "❌ Build failed" - exit 1 -fi - -# Create configs -echo "πŸ“ Creating configurations..." - -CURRENT_DIR=$(pwd) - -cat > test-agent1/config.toml << EOF -agent_id = "11111111-1111-1111-1111-111111111111" -name = "test-agent-1" -server_url = "http://localhost:8000" -api_key = "test-key" -p2p_only_mode = true -collection_interval = 30 -heartbeat_interval = 60 -tags = [] - -[p2p] -enabled = true -listen_port = 8443 -peers = ["127.0.0.1:8444"] -cert_path = "$CURRENT_DIR/test-agent1/certs/agent.crt" -key_path = "$CURRENT_DIR/test-agent1/certs/agent.key" -ca_cert_path = "$CURRENT_DIR/test-agent1/certs/ca.crt" -auto_generate_certs = true -EOF - -cat > test-agent2/config.toml << EOF -agent_id = "22222222-2222-2222-2222-222222222222" -name = "test-agent-2" -server_url = "http://localhost:8000" -api_key = "test-key" -p2p_only_mode = true -collection_interval = 30 -heartbeat_interval = 60 -tags = [] - -[p2p] -enabled = true -listen_port = 8444 -peers = ["127.0.0.1:8443"] -cert_path = "$CURRENT_DIR/test-agent2/certs/agent.crt" -key_path = "$CURRENT_DIR/test-agent2/certs/agent.key" -ca_cert_path = "$CURRENT_DIR/test-agent2/certs/ca.crt" -auto_generate_certs = true -EOF - -# Start Agent 1 -echo "πŸš€ Starting Agent 1 (port 8443)..." -cd test-agent1 -RUST_LOG=info ../target/release/csf-agent > agent.log 2>&1 & -AGENT1_PID=$! -cd .. -echo " PID: $AGENT1_PID" - -# Wait for Agent 1 to start and generate certs -echo "⏳ Waiting for Agent 1 to generate certificates..." -sleep 4 - -# Copy CA cert from Agent 1 to Agent 2 -if [ -f "test-agent1/certs/ca.crt" ]; then - echo "πŸ“‹ Sharing CA certificate with Agent 2..." - cp test-agent1/certs/ca.crt test-agent2/certs/ - cp test-agent1/certs/ca.key test-agent2/certs/ - echo "βœ… CA certificate shared" -else - echo "❌ CA cert not found at test-agent1/certs/ca.crt" - echo " Check Agent 1 log for errors" - tail -10 test-agent1/agent.log - exit 1 -fi - -# Start Agent 2 -echo "πŸš€ Starting Agent 2 (port 8444)..." -cd test-agent2 -RUST_LOG=info ../target/release/csf-agent > agent.log 2>&1 & -AGENT2_PID=$! -cd .. -echo " PID: $AGENT2_PID" - -# Wait for connection -echo "⏳ Waiting for connection (10 seconds)..." -sleep 10 - -# Check logs -echo "" -echo "πŸ“Š Agent 1 Log:" -echo "===============" -tail -25 test-agent1/agent.log - -echo "" -echo "πŸ“Š Agent 2 Log:" -echo "===============" -tail -25 test-agent2/agent.log - -echo "" -echo "πŸ” Checking for successful P2P connection..." -if grep -q "Connected to peer" test-agent1/agent.log && grep -q "Connected to peer" test-agent2/agent.log; then - echo "βœ… SUCCESS! Both agents connected via mTLS" -elif grep -q "P2P server listening" test-agent1/agent.log && grep -q "P2P server listening" test-agent2/agent.log; then - echo "⚠️ Servers running but connection pending. Check logs for details." -else - echo "❌ Connection not established" -fi - -echo "" -echo "πŸ“ Process Info:" -echo " Agent 1 PID: $AGENT1_PID" -echo " Agent 2 PID: $AGENT2_PID" -echo "" -echo "πŸ›‘ To stop agents:" -echo " kill $AGENT1_PID $AGENT2_PID" -echo "" -echo "πŸ“– To follow logs:" -echo " tail -f test-agent1/agent.log" -echo " tail -f test-agent2/agent.log" -echo "" -echo "🧹 To cleanup:" -echo " kill $AGENT1_PID $AGENT2_PID 2>/dev/null" -echo " rm -rf test-agent1 test-agent2" diff --git a/backend/.dockerignore b/backend/.dockerignore deleted file mode 100644 index 3032ba7..0000000 --- a/backend/.dockerignore +++ /dev/null @@ -1,5 +0,0 @@ -.git -.gitignore -target/ -finance.db -finance.db-journal diff --git a/backend/Dockerfile.dev b/backend/Dockerfile.dev deleted file mode 100644 index c58f0f5..0000000 --- a/backend/Dockerfile.dev +++ /dev/null @@ -1,29 +0,0 @@ -# Development Dockerfile for FinanceVault Backend -FROM rust:latest - -WORKDIR /usr/src/app - -# Install system dependencies -RUN apt-get update && apt-get install -y \ - pkg-config \ - libssl-dev \ - sqlite3 \ - && rm -rf /var/lib/apt/lists/* - -# Install cargo-watch for hot reload -RUN cargo install cargo-watch - -# Create data directory for SQLite -RUN mkdir -p /data - -# Expose backend port -EXPOSE 8000 - -# Set environment variables -ENV DATABASE_URL=sqlite:/data/finance.db -ENV RUST_LOG=debug -ENV CARGO_HOME=/usr/local/cargo - -# The source code will be mounted as a volume -# Command will be overridden in docker-compose.dev.yml -CMD ["cargo", "watch", "-x", "run"] diff --git a/backend/entity/Cargo.toml b/backend/entity/Cargo.toml deleted file mode 100644 index 6c3634e..0000000 --- a/backend/entity/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "entity" -version = "0.1.0" -edition = "2021" - -[dependencies] -sea-orm = { version = "1.1.0", features = [ "sqlx-sqlite", "runtime-tokio-rustls", "macros" ] } -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -uuid = { version = "1.0", features = ["v4", "serde"] } -chrono = { version = "0.4", features = ["serde"] } -utoipa = { version = "4.2", features = ["uuid", "chrono"] } \ No newline at end of file diff --git a/backend/migration/Cargo.lock b/backend/migration/Cargo.lock deleted file mode 100644 index 351dd8a..0000000 --- a/backend/migration/Cargo.lock +++ /dev/null @@ -1,2644 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "aliasable" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" -dependencies = [ - "windows-sys 0.60.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.60.2", -] - -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.5.0", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", - "tokio", -] - -[[package]] -name = "async-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" -dependencies = [ - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "windows-sys 0.61.2", -] - -[[package]] -name = "async-lock" -version = "3.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" -dependencies = [ - "event-listener 5.4.1", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-std" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" -dependencies = [ - "async-attributes", - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "atoi" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" -dependencies = [ - "num-traits", -] - -[[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.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" -dependencies = [ - "async-channel 2.5.0", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "cc" -version = "1.2.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "chrono" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" -dependencies = [ - "iana-time-zone", - "num-traits", - "windows-link", -] - -[[package]] -name = "clap" -version = "4.5.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "clap_lex" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crossbeam-queue" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", - "unicode-xid", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", - "subtle", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "dotenvy" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" -dependencies = [ - "serde", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "etcetera" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" -dependencies = [ - "cfg-if", - "home", - "windows-sys 0.48.0", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener 5.4.1", - "pin-project-lite", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "find-msvc-tools" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-intrusive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - -[[package]] -name = "hashlink" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" -dependencies = [ - "hashbrown 0.15.5", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest", -] - -[[package]] -name = "home" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" -dependencies = [ - "equivalent", - "hashbrown 0.16.0", -] - -[[package]] -name = "inherent" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c727f80bfa4a6c6e2508d2f05b6f4bfce242030bd88ed15ae5331c5b5d30fba7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "js-sys" -version = "0.3.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" - -[[package]] -name = "libredox" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" -dependencies = [ - "bitflags", - "libc", - "redox_syscall 0.7.0", -] - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" -dependencies = [ - "value-bag", -] - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest", -] - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "migration" -version = "0.1.0" -dependencies = [ - "async-std", - "sea-orm-migration", -] - -[[package]] -name = "mio" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - -[[package]] -name = "ordered-float" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" -dependencies = [ - "num-traits", -] - -[[package]] -name = "ouroboros" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59" -dependencies = [ - "aliasable", - "ouroboros_macro", - "static_assertions", -] - -[[package]] -name = "ouroboros_macro" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.5.18", - "smallvec", - "windows-link", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "polling" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "potential_utf" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" -dependencies = [ - "zerovec", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "proc-macro2" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" -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.108", - "version_check", - "yansi", -] - -[[package]] -name = "quote" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_syscall" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pki-types" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sea-bae" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25" -dependencies = [ - "heck 0.4.1", - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "sea-orm" -version = "1.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "699b1ec145a6530c8f862eed7529d8a6068392e628d81cc70182934001e9c2a3" -dependencies = [ - "async-stream", - "async-trait", - "derive_more", - "futures-util", - "log", - "ouroboros", - "sea-orm-macros", - "sea-query", - "sea-query-binder", - "serde", - "sqlx", - "strum", - "thiserror", - "tracing", - "url", -] - -[[package]] -name = "sea-orm-cli" -version = "1.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cd31ebb07814d4c7b73796708bfab6c13d22f8db072cdb5115f967f4d5d2c" -dependencies = [ - "chrono", - "clap", - "dotenvy", - "glob", - "regex", - "sea-schema", - "sqlx", - "tokio", - "tracing", - "tracing-subscriber", - "url", -] - -[[package]] -name = "sea-orm-macros" -version = "1.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c964f4b7f34f53decf381bc88f03187b9355e07f356ce65544626e781a9585" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "sea-bae", - "syn 2.0.108", - "unicode-ident", -] - -[[package]] -name = "sea-orm-migration" -version = "1.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977e3f71486b04371026d1ecd899f49cf437f832cd11d463f8948ee02e47ed9e" -dependencies = [ - "async-trait", - "clap", - "dotenvy", - "sea-orm", - "sea-orm-cli", - "sea-schema", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "sea-query" -version = "0.32.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a5d1c518eaf5eda38e5773f902b26ab6d5e9e9e2bb2349ca6c64cf96f80448c" -dependencies = [ - "inherent", - "ordered-float", - "sea-query-derive", -] - -[[package]] -name = "sea-query-binder" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0019f47430f7995af63deda77e238c17323359af241233ec768aba1faea7608" -dependencies = [ - "sea-query", - "sqlx", -] - -[[package]] -name = "sea-query-derive" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae0cbad6ab996955664982739354128c58d16e126114fe88c2a493642502aab" -dependencies = [ - "darling", - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.108", - "thiserror", -] - -[[package]] -name = "sea-schema" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2239ff574c04858ca77485f112afea1a15e53135d3097d0c86509cef1def1338" -dependencies = [ - "futures", - "sea-query", - "sea-query-binder", - "sea-schema-derive", - "sqlx", -] - -[[package]] -name = "sea-schema-derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "serde_json" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -dependencies = [ - "serde", -] - -[[package]] -name = "socket2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "sqlx" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" -dependencies = [ - "sqlx-core", - "sqlx-macros", - "sqlx-postgres", -] - -[[package]] -name = "sqlx-core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" -dependencies = [ - "base64", - "bytes", - "crc", - "crossbeam-queue", - "either", - "event-listener 5.4.1", - "futures-core", - "futures-intrusive", - "futures-io", - "futures-util", - "hashbrown 0.15.5", - "hashlink", - "indexmap", - "log", - "memchr", - "once_cell", - "percent-encoding", - "rustls", - "serde", - "serde_json", - "sha2", - "smallvec", - "thiserror", - "tokio", - "tokio-stream", - "tracing", - "url", - "webpki-roots 0.26.11", -] - -[[package]] -name = "sqlx-macros" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" -dependencies = [ - "proc-macro2", - "quote", - "sqlx-core", - "sqlx-macros-core", - "syn 2.0.108", -] - -[[package]] -name = "sqlx-macros-core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" -dependencies = [ - "dotenvy", - "either", - "heck 0.5.0", - "hex", - "once_cell", - "proc-macro2", - "quote", - "serde", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-postgres", - "syn 2.0.108", - "tokio", - "url", -] - -[[package]] -name = "sqlx-postgres" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" -dependencies = [ - "atoi", - "base64", - "bitflags", - "byteorder", - "crc", - "dotenvy", - "etcetera", - "futures-channel", - "futures-core", - "futures-util", - "hex", - "hkdf", - "hmac", - "home", - "itoa", - "log", - "md-5", - "memchr", - "once_cell", - "rand", - "serde", - "serde_json", - "sha2", - "smallvec", - "sqlx-core", - "stringprep", - "thiserror", - "tracing", - "whoami", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "stringprep" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" -dependencies = [ - "unicode-bidi", - "unicode-normalization", - "unicode-properties", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "thiserror" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" -dependencies = [ - "matchers", - "once_cell", - "regex-automata", - "sharded-slab", - "thread_local", - "tracing", - "tracing-core", -] - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicode-bidi" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" - -[[package]] -name = "unicode-ident" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" - -[[package]] -name = "unicode-normalization" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-properties" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "value-bag" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[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.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.108", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.3", -] - -[[package]] -name = "webpki-roots" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "whoami" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" -dependencies = [ - "libredox", - "wasite", -] - -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-sys" -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.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "yansi" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.108", -] diff --git a/backend/migration/Cargo.toml b/backend/migration/Cargo.toml deleted file mode 100644 index 7390673..0000000 --- a/backend/migration/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "migration" -version = "0.1.0" -edition = "2021" -publish = false - -[lib] -name = "migration" -path = "src/lib.rs" - -[dependencies] -async-std = { version = "1", features = ["attributes", "tokio1"] } - -[dependencies.sea-orm-migration] -version = "1.1.0" -features = [ - # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. - # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. - # e.g. - "runtime-tokio-rustls", # `ASYNC_RUNTIME` feature - "sqlx-postgres", # `DATABASE_DRIVER` feature -] diff --git a/backend/src/routes/updates.rs b/backend/src/routes/updates.rs deleted file mode 100644 index 80c9f22..0000000 --- a/backend/src/routes/updates.rs +++ /dev/null @@ -1,485 +0,0 @@ -use axum::{ - extract::State, - http::StatusCode, - response::{IntoResponse, Response}, - routing::{get, post}, - Json, Router, -}; -use serde::{Deserialize, Serialize}; -use tokio::process::Command; - -use crate::AppState; - -#[derive(Debug, Serialize, Deserialize)] -pub struct UpdateStatus { - pub status: String, - pub message: String, - pub progress: u8, - pub version: Option, - pub timestamp: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct VersionInfo { - pub current_version: String, - pub latest_version: String, - pub update_available: bool, - pub changelog: Option, - pub release_url: String, - pub is_prerelease: bool, - pub latest_beta_version: Option, - pub beta_release_url: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct UpdateRequest { - pub version: String, -} - -#[derive(Debug, Serialize)] -pub struct UpdateResponse { - pub success: bool, - pub message: String, -} - -/// Get current version and check for updates -#[utoipa::path( - get, - path = "/api/updates/check", - responses( - (status = 200, description = "Version information retrieved successfully", body = VersionInfo), - (status = 500, description = "Failed to check for updates") - ), - tag = "Updates" -)] -pub async fn check_updates(State(_state): State) -> Result, AppError> { - let current_version = env!("CARGO_PKG_VERSION").to_string(); - - // Fetch latest release from GitHub - let client = reqwest::Client::builder() - .user_agent("CSF-Core-Updater") - .build() - .map_err(|e| AppError::InternalError(format!("Failed to create HTTP client: {}", e)))?; - - // Get latest stable release - let response = client - .get("https://api.github.com/repos/CS-Foundry/CSF-Core/releases/latest") - .send() - .await - .map_err(|e| AppError::InternalError(format!("Failed to fetch releases: {}", e)))?; - - if !response.status().is_success() { - return Err(AppError::InternalError(format!( - "GitHub API returned status: {}", - response.status() - ))); - } - - let release: GitHubRelease = response - .json() - .await - .map_err(|e| AppError::InternalError(format!("Failed to parse release data: {}", e)))?; - - let latest_version = release.tag_name.trim_start_matches('v').to_string(); - let update_available = version_compare(¤t_version, &latest_version); - - // Check for beta releases - let all_releases_response = client - .get("https://api.github.com/repos/CS-Foundry/CSF-Core/releases") - .send() - .await - .map_err(|e| AppError::InternalError(format!("Failed to fetch all releases: {}", e)))?; - - let all_releases: Vec = all_releases_response - .json() - .await - .map_err(|e| AppError::InternalError(format!("Failed to parse releases data: {}", e)))?; - - // Find latest beta release - let latest_beta = all_releases.iter().find(|r| r.prerelease).map(|r| { - ( - r.tag_name.trim_start_matches('v').to_string(), - r.html_url.clone(), - ) - }); - - Ok(Json(VersionInfo { - current_version, - latest_version: latest_version.clone(), - update_available, - changelog: Some(release.body), - release_url: release.html_url, - is_prerelease: release.prerelease, - latest_beta_version: latest_beta.as_ref().map(|(v, _)| v.clone()), - beta_release_url: latest_beta.map(|(_, url)| url), - })) -} - -/// Get update status -#[utoipa::path( - get, - path = "/api/updates/status", - responses( - (status = 200, description = "Update status retrieved successfully", body = UpdateStatus), - (status = 404, description = "No update in progress"), - (status = 500, description = "Failed to read status") - ), - tag = "Updates" -)] -pub async fn get_update_status( - State(_state): State, -) -> Result, AppError> { - // Use /var/tmp instead of /tmp to avoid systemd PrivateTmp isolation - let status_file = "/var/tmp/csf-core-update-status.json"; - - match tokio::fs::read_to_string(status_file).await { - Ok(content) => match serde_json::from_str::(&content) { - Ok(status) => Ok(Json(status)), - Err(e) => Err(AppError::InternalError(format!( - "Failed to parse status file: {}", - e - ))), - }, - Err(_) => { - // No status file means no update in progress - Ok(Json(UpdateStatus { - status: "idle".to_string(), - message: "No update in progress".to_string(), - progress: 0, - version: None, - timestamp: None, - })) - } - } -} - -/// Trigger update installation -#[utoipa::path( - post, - path = "/api/updates/install", - request_body = UpdateRequest, - responses( - (status = 200, description = "Update initiated successfully", body = UpdateResponse), - (status = 400, description = "Invalid request"), - (status = 500, description = "Failed to start update") - ), - tag = "Updates" -)] -pub async fn install_update( - State(_state): State, - Json(payload): Json, -) -> Result, AppError> { - tracing::info!( - "Update installation requested for version: {}", - payload.version - ); - - let current_version = env!("CARGO_PKG_VERSION").to_string(); - tracing::info!("Current version: {}", current_version); - - // Safety check: don't downgrade - if !version_compare(¤t_version, &payload.version) { - tracing::warn!( - "Update rejected: Cannot install version {} (current: {})", - payload.version, - current_version - ); - return Ok(Json(UpdateResponse { - success: false, - message: "Cannot install an older or same version".to_string(), - })); - } - - // Find the update script - try multiple locations - let mut possible_paths: Vec = vec![ - // Production path (daemon service) - std::path::PathBuf::from("/opt/csf-core/scripts/update.sh"), - ]; - - // Development paths - if let Ok(dir) = std::env::current_dir() { - // When running from /opt/csf-core/backend - possible_paths.push(dir.join("../scripts/update.sh")); - // When running from project root - possible_paths.push(dir.join("scripts/update.sh")); - // When running from backend directory - possible_paths.push(dir.join("../../scripts/update.sh")); - } - - tracing::debug!("Searching for update script in: {:?}", possible_paths); - - let script_path = match possible_paths.iter().find(|&p| p.exists()) { - Some(path) => path.clone(), - None => { - let error_msg = format!( - "Update script not found in any expected location. Searched paths: {:?}. Note: Updates can only be performed in production installations, not during local development.", - possible_paths - ); - tracing::error!("{}", error_msg); - return Err(AppError::InternalError( - "Update functionality is only available in production installations. The update script was not found on this system.".to_string() - )); - } - }; - - tracing::info!("Found update script at: {:?}", script_path); - - // Clone version for use in response message - let version_for_message = payload.version.clone(); - - // Create initial status file to indicate update has started - let timestamp = std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs(); - - let status_content = format!( - r#"{{ - "status": "in_progress", - "message": "Initializing update process...", - "progress": 0, - "version": "{}", - "timestamp": "{}" -}}"#, - payload.version, timestamp - ); - - // Use /var/tmp instead of /tmp to avoid systemd PrivateTmp isolation - if let Err(e) = tokio::fs::write("/var/tmp/csf-core-update-status.json", status_content).await { - tracing::warn!("Failed to create initial status file: {}", e); - } - - // Start update process in background with proper output handling - let script_path_clone = script_path.clone(); - let version_clone = payload.version.clone(); - - tokio::spawn(async move { - tracing::info!("Spawning update process for version {}", version_clone); - - // Log current user for debugging - let current_user = std::env::var("USER").unwrap_or_else(|_| "unknown".to_string()); - tracing::info!("Running as user: {}", current_user); - - // Check if we're running as root - let is_root = std::fs::metadata("/etc/shadow") - .and_then(|_| std::fs::File::open("/etc/shadow")) - .is_ok(); - - tracing::info!("Running as root: {}", is_root); - - // Build command - use sudo nohup to detach from parent process - // This ensures the update continues even when the backend service is stopped - // sudoers entry: csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* - let mut command = if is_root { - // Running as root, execute script directly with nohup - let mut cmd = Command::new("nohup"); - cmd.arg("/bin/bash"); - cmd.arg(&script_path_clone); - cmd - } else { - // Running as csf-core user - use sudo nohup (not nohup sudo!) - // This matches the sudoers entry exactly - let mut cmd = Command::new("sudo"); - cmd.arg("/usr/bin/nohup"); - cmd.arg("/bin/bash"); - cmd.arg(&script_path_clone); - cmd - }; - - // Set up environment variables that the script might need - command.env( - "PATH", - "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - ); - command.env( - "HOME", - std::env::var("HOME").unwrap_or_else(|_| "/root".to_string()), - ); - command.env("LANG", "C.UTF-8"); - command.env("LC_ALL", "C.UTF-8"); - - // Set working directory to script location - if let Some(script_dir) = script_path_clone.parent() { - command.current_dir(script_dir); - tracing::info!("Working directory: {:?}", script_dir); - } - - command - .arg(&version_clone) - // Redirect stdout/stderr to log file for debugging - .stdin(std::process::Stdio::null()); - - // Keep stdout/stderr open so we can see errors in the log - // The script itself redirects to /var/tmp/csf-core-update.log - - tracing::info!("Executing command: {:?}", command); - tracing::info!( - "Command environment: PATH={}, HOME={}", - std::env::var("PATH").unwrap_or_default(), - std::env::var("HOME").unwrap_or_default() - ); - - match command.spawn() { - Ok(child) => { - tracing::info!( - "Update process started successfully (PID: {:?}) and detached", - child.id() - ); - - // Process is detached - it will continue even if backend stops - // Users can monitor progress via /var/tmp/csf-core-update-status.json - tracing::info!( - "Update running in background. Monitor: /var/tmp/csf-core-update-status.json" - ); - } - Err(e) => { - tracing::error!("Failed to start update process: {}", e); - - // Write error to status file - let ts = std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs(); - - let error_status = format!( - r#"{{ - "status": "error", - "message": "Failed to start update script: {}", - "progress": 0, - "version": "{}", - "timestamp": "{}" -}}"#, - e, version_clone, ts - ); - - // Use /var/tmp instead of /tmp - let _ = - tokio::fs::write("/var/tmp/csf-core-update-status.json", error_status).await; - } - } - }); - - Ok(Json(UpdateResponse { - success: true, - message: format!( - "Update to version {} initiated. The application will restart shortly.", - version_for_message - ), - })) -} - -/// Get changelog for a specific version -#[utoipa::path( - get, - path = "/api/updates/changelog/{version}", - params( - ("version" = String, Path, description = "Version to get changelog for") - ), - responses( - (status = 200, description = "Changelog retrieved successfully"), - (status = 404, description = "Version not found"), - (status = 500, description = "Failed to fetch changelog") - ), - tag = "Updates" -)] -pub async fn get_changelog( - State(_state): State, - axum::extract::Path(version): axum::extract::Path, -) -> Result, AppError> { - let client = reqwest::Client::builder() - .user_agent("CSF-Core-Updater") - .build() - .map_err(|e| AppError::InternalError(format!("Failed to create HTTP client: {}", e)))?; - - let url = format!( - "https://api.github.com/repos/CS-Foundry/CSF-Core/releases/tags/v{}", - version.trim_start_matches('v') - ); - - let response = client - .get(&url) - .send() - .await - .map_err(|e| AppError::InternalError(format!("Failed to fetch release: {}", e)))?; - - if response.status() == 404 { - return Err(AppError::NotFound(format!("Version {} not found", version))); - } - - if !response.status().is_success() { - return Err(AppError::InternalError(format!( - "GitHub API returned status: {}", - response.status() - ))); - } - - let release: GitHubRelease = response - .json() - .await - .map_err(|e| AppError::InternalError(format!("Failed to parse release data: {}", e)))?; - - Ok(Json(release.body)) -} - -// Helper structs for GitHub API -#[derive(Debug, Deserialize)] -struct GitHubRelease { - tag_name: String, - body: String, - html_url: String, - prerelease: bool, -} - -// Compare versions (returns true if v2 is newer than v1) -fn version_compare(v1: &str, v2: &str) -> bool { - let parse_version = - |v: &str| -> Vec { v.split('.').filter_map(|s| s.parse::().ok()).collect() }; - - let v1_parts = parse_version(v1); - let v2_parts = parse_version(v2); - - for i in 0..v1_parts.len().max(v2_parts.len()) { - let p1 = v1_parts.get(i).copied().unwrap_or(0); - let p2 = v2_parts.get(i).copied().unwrap_or(0); - - if p2 > p1 { - return true; - } else if p2 < p1 { - return false; - } - } - - false -} - -// Error handling -#[derive(Debug)] -pub enum AppError { - InternalError(String), - NotFound(String), -} - -impl IntoResponse for AppError { - fn into_response(self) -> Response { - let (status, message) = match &self { - AppError::InternalError(msg) => { - tracing::error!("Internal error: {}", msg); - (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()) - } - AppError::NotFound(msg) => { - tracing::warn!("Not found: {}", msg); - (StatusCode::NOT_FOUND, msg.clone()) - } - }; - - (status, Json(serde_json::json!({ "error": message }))).into_response() - } -} - -pub fn router() -> Router { - Router::new() - .route("/updates/check", get(check_updates)) - .route("/updates/status", get(get_update_status)) - .route("/updates/install", post(install_update)) - .route("/updates/changelog/:version", get(get_changelog)) -} diff --git a/cli/Cargo.toml b/cli/Cargo.toml new file mode 100644 index 0000000..df0636c --- /dev/null +++ b/cli/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "cli" +version.workspace = true +edition.workspace = true +license.workspace = true + +[[bin]] +name = "csf" +path = "src/main.rs" + +[dependencies] +# Internal dependencies +shared = { path = "../control-plane/shared/shared" } + +# Async runtime +tokio = { workspace = true } + +# Logging +tracing = { workspace = true } + +# Utilities +dotenvy = { workspace = true } +anyhow = { workspace = true } diff --git a/cli/Dockerfile.dev b/cli/Dockerfile.dev new file mode 100644 index 0000000..c646c76 --- /dev/null +++ b/cli/Dockerfile.dev @@ -0,0 +1,34 @@ +# Development Dockerfile for CLI +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY agent/Cargo.toml ./agent/ +COPY entity/Cargo.toml ./entity/ +COPY control-plane/api-gateway/Cargo.toml ./control-plane/api-gateway/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ + +# Copy service and dependencies +COPY cli/ ./cli/ +COPY shared/ ./shared/ +COPY migration/ ./migration/ + +# Pre-build dependencies (this layer will be cached) +RUN cargo build --bin csf + +# Default command (can be overridden in docker-compose) +CMD ["cargo", "run", "--bin", "csf"] diff --git a/cli/src/main.rs b/cli/src/main.rs new file mode 100644 index 0000000..b08ec87 --- /dev/null +++ b/cli/src/main.rs @@ -0,0 +1,26 @@ +use anyhow::Result; + +#[tokio::main] +async fn main() -> Result<()> { + // Load .env file if it exists + dotenvy::dotenv().ok(); + + // Initialize shared logger + shared::init_logger(); + + tracing::info!("πŸ–₯️ CSF CLI starting..."); + tracing::info!("Version: {}", env!("CARGO_PKG_VERSION")); + + // TODO: Implement CLI functionality + // CLI will provide: + // - User management commands + // - Resource management + // - System configuration + // - Deployment tools + + tracing::warn!("⚠️ CLI functionality not yet implemented"); + tracing::info!("βœ… Test log: CLI initialized successfully"); + tracing::info!("πŸ’‘ Use 'csf --help' to see available commands (once implemented)"); + + Ok(()) +} diff --git a/backend/Cargo.lock b/control-plane/api-gateway/Cargo.lock similarity index 100% rename from backend/Cargo.lock rename to control-plane/api-gateway/Cargo.lock diff --git a/control-plane/api-gateway/Cargo.toml b/control-plane/api-gateway/Cargo.toml new file mode 100644 index 0000000..4c19532 --- /dev/null +++ b/control-plane/api-gateway/Cargo.toml @@ -0,0 +1,71 @@ +[package] +name = "api-gateway" +version.workspace = true +edition.workspace = true +license.workspace = true + +[[bin]] +name = "api-gateway" +path = "src/main.rs" + +[dependencies] +# Internal dependencies +entity = { path = "../shared/entity" } +migration = { path = "../shared/migration" } +shared = { path = "../shared/shared" } + +# Async runtime +tokio = { workspace = true } +async-trait = { workspace = true } + +# Database +sea-orm = { workspace = true } + +# Web framework +axum = { workspace = true } +tower-http = { workspace = true } +hyper = { workspace = true } +hyper-util = { workspace = true } +http = { workspace = true } + +# Serialization +serde = { workspace = true } +serde_json = { workspace = true } + +# Logging +tracing = { workspace = true } +tracing-subscriber = { workspace = true } + +# Security +jsonwebtoken = { workspace = true } +bcrypt = { workspace = true } +rsa = { workspace = true } +totp-rs = { workspace = true } + +# Utilities +uuid = { workspace = true } +chrono = { workspace = true } +dotenvy = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } + +# OpenAPI +utoipa = { workspace = true } +utoipa-swagger-ui = { workspace = true } + +# Other +rand = { workspace = true } +base64 = { workspace = true } +sha1 = { workspace = true } +sha2 = { workspace = true } +cookie = { workspace = true } +qrcode = { workspace = true } +image = { workspace = true } +sysinfo = { workspace = true } +bollard = { workspace = true } +futures-util = { workspace = true } +reqwest = { workspace = true } + +[features] +default = [] +vendored-openssl = [] diff --git a/backend/Dockerfile b/control-plane/api-gateway/Dockerfile similarity index 86% rename from backend/Dockerfile rename to control-plane/api-gateway/Dockerfile index 899fb56..2102266 100644 --- a/backend/Dockerfile +++ b/control-plane/api-gateway/Dockerfile @@ -1,4 +1,4 @@ -# Multi-stage build for FinanceVault Backend (with embedded frontend proxy) +# Multi-stage build for API Gateway ################### # Chef Stage - Prepare Recipe @@ -20,9 +20,9 @@ COPY entity/src ./entity/src RUN cargo chef prepare --recipe-path recipe.json ################### -# Backend Build Stage +# API Gateway Build Stage ################### -FROM chef AS backend-builder +FROM chef AS api-gateway-builder # Install system dependencies RUN apt-get update && apt-get install -y \ @@ -52,7 +52,7 @@ COPY migration/src ./migration/src COPY entity/src ./entity/src # Fix: Update timestamps to force rebuild, otherwise cargo might skip building if host files are older than dummy files RUN touch src/main.rs migration/src/lib.rs entity/src/lib.rs -RUN cargo build --release +RUN cargo build --release --bin api-gateway ################### # Final Runtime Stage @@ -72,10 +72,10 @@ RUN apt-get update && apt-get install -y \ # Create data directory for SQLite RUN mkdir -p /data -# Copy backend binary from builder -COPY --from=backend-builder /usr/src/app/target/release/backend /app/backend +# Copy api-gateway binary from builder +COPY --from=api-gateway-builder /usr/src/app/target/release/api-gateway /app/api-gateway -# Expose backend port +# Expose api-gateway port EXPOSE 8000 # Set environment variables @@ -86,5 +86,5 @@ ENV RUST_LOG=info HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:8000/api/system/health || exit 1 -# Start backend -CMD ["./backend"] \ No newline at end of file +# Start API Gateway +CMD ["./api-gateway"] \ No newline at end of file diff --git a/control-plane/api-gateway/Dockerfile.dev b/control-plane/api-gateway/Dockerfile.dev new file mode 100644 index 0000000..bd61565 --- /dev/null +++ b/control-plane/api-gateway/Dockerfile.dev @@ -0,0 +1,38 @@ +# Development Dockerfile for API Gateway +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + libpq-dev \ + && cargo install cargo-watch --version 7.8.0 --locked \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY agent/Cargo.toml ./agent/ +COPY cli/Cargo.toml ./cli/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ + +# Copy control-plane and dependencies +COPY control-plane/api-gateway/ ./control-plane/api-gateway/ +COPY shared/ ./shared/ +COPY migration/ ./migration/ +COPY entity/ ./entity/ + +# Pre-build dependencies +RUN cargo build --bin api-gateway + +# Expose port +EXPOSE 8000 + +CMD ["cargo", "watch", "-x", "run --bin api-gateway"] diff --git a/backend/docker-compose.yml b/control-plane/api-gateway/docker-compose.yml similarity index 100% rename from backend/docker-compose.yml rename to control-plane/api-gateway/docker-compose.yml diff --git a/backend/src/api_docs.rs b/control-plane/api-gateway/src/api_docs.rs similarity index 100% rename from backend/src/api_docs.rs rename to control-plane/api-gateway/src/api_docs.rs diff --git a/backend/src/auth/crypto.rs b/control-plane/api-gateway/src/auth/crypto.rs similarity index 95% rename from backend/src/auth/crypto.rs rename to control-plane/api-gateway/src/auth/crypto.rs index 3ab72f7..031dbea 100644 --- a/backend/src/auth/crypto.rs +++ b/control-plane/api-gateway/src/auth/crypto.rs @@ -57,13 +57,13 @@ impl RsaKeyPair { pub fn decrypt_password(encrypted_password: &str, private_key: &str) -> CryptoResult { use rsa::Oaep; - use sha1::Sha1; + use sha2::Sha256; let private_key = RsaPrivateKey::from_pkcs1_pem(private_key)?; let encrypted_bytes = base64::engine::general_purpose::STANDARD.decode(encrypted_password)?; - // Use SHA-1 to match node-forge's default RSA-OAEP implementation - let padding = Oaep::new::(); + // Use SHA-256 for RSA-OAEP padding + let padding = Oaep::new::(); let decrypted = private_key.decrypt(padding, &encrypted_bytes)?; String::from_utf8(decrypted).map_err(|_| CryptoError::InvalidEncryptedData) diff --git a/backend/src/auth/jwt.rs b/control-plane/api-gateway/src/auth/jwt.rs similarity index 100% rename from backend/src/auth/jwt.rs rename to control-plane/api-gateway/src/auth/jwt.rs diff --git a/backend/src/auth/middleware.rs b/control-plane/api-gateway/src/auth/middleware.rs similarity index 100% rename from backend/src/auth/middleware.rs rename to control-plane/api-gateway/src/auth/middleware.rs diff --git a/backend/src/auth/mod.rs b/control-plane/api-gateway/src/auth/mod.rs similarity index 100% rename from backend/src/auth/mod.rs rename to control-plane/api-gateway/src/auth/mod.rs diff --git a/backend/src/auth_service.rs b/control-plane/api-gateway/src/auth_service.rs similarity index 100% rename from backend/src/auth_service.rs rename to control-plane/api-gateway/src/auth_service.rs diff --git a/backend/src/db.rs b/control-plane/api-gateway/src/db.rs similarity index 100% rename from backend/src/db.rs rename to control-plane/api-gateway/src/db.rs diff --git a/backend/src/docker_service.rs b/control-plane/api-gateway/src/docker_service.rs similarity index 100% rename from backend/src/docker_service.rs rename to control-plane/api-gateway/src/docker_service.rs diff --git a/backend/src/init.rs b/control-plane/api-gateway/src/init.rs similarity index 100% rename from backend/src/init.rs rename to control-plane/api-gateway/src/init.rs diff --git a/backend/src/main.rs b/control-plane/api-gateway/src/main.rs similarity index 100% rename from backend/src/main.rs rename to control-plane/api-gateway/src/main.rs diff --git a/backend/src/rbac_service.rs b/control-plane/api-gateway/src/rbac_service.rs similarity index 100% rename from backend/src/rbac_service.rs rename to control-plane/api-gateway/src/rbac_service.rs diff --git a/backend/src/routes/agents.rs b/control-plane/api-gateway/src/routes/agents.rs similarity index 100% rename from backend/src/routes/agents.rs rename to control-plane/api-gateway/src/routes/agents.rs diff --git a/backend/src/routes/expenses.rs b/control-plane/api-gateway/src/routes/expenses.rs similarity index 100% rename from backend/src/routes/expenses.rs rename to control-plane/api-gateway/src/routes/expenses.rs diff --git a/backend/src/routes/frontend.rs b/control-plane/api-gateway/src/routes/frontend.rs similarity index 100% rename from backend/src/routes/frontend.rs rename to control-plane/api-gateway/src/routes/frontend.rs diff --git a/backend/src/routes/marketplace.rs b/control-plane/api-gateway/src/routes/marketplace.rs similarity index 100% rename from backend/src/routes/marketplace.rs rename to control-plane/api-gateway/src/routes/marketplace.rs diff --git a/backend/src/routes/mod.rs b/control-plane/api-gateway/src/routes/mod.rs similarity index 100% rename from backend/src/routes/mod.rs rename to control-plane/api-gateway/src/routes/mod.rs diff --git a/backend/src/routes/organizations.rs b/control-plane/api-gateway/src/routes/organizations.rs similarity index 100% rename from backend/src/routes/organizations.rs rename to control-plane/api-gateway/src/routes/organizations.rs diff --git a/backend/src/routes/resource_groups.rs b/control-plane/api-gateway/src/routes/resource_groups.rs similarity index 100% rename from backend/src/routes/resource_groups.rs rename to control-plane/api-gateway/src/routes/resource_groups.rs diff --git a/backend/src/routes/resources.rs b/control-plane/api-gateway/src/routes/resources.rs similarity index 100% rename from backend/src/routes/resources.rs rename to control-plane/api-gateway/src/routes/resources.rs diff --git a/backend/src/routes/subscriptions.rs b/control-plane/api-gateway/src/routes/subscriptions.rs similarity index 100% rename from backend/src/routes/subscriptions.rs rename to control-plane/api-gateway/src/routes/subscriptions.rs diff --git a/backend/src/routes/system.rs b/control-plane/api-gateway/src/routes/system.rs similarity index 86% rename from backend/src/routes/system.rs rename to control-plane/api-gateway/src/routes/system.rs index 8b7f9c3..1c97d44 100644 --- a/backend/src/routes/system.rs +++ b/control-plane/api-gateway/src/routes/system.rs @@ -1,6 +1,7 @@ use axum::{extract::State, response::Json, routing::get, Router}; use serde::{Deserialize, Serialize}; +use crate::auth::middleware::AuthenticatedUser; use crate::system_collector::{LocalSystemCollector, LocalSystemMetrics}; use crate::AppState; @@ -41,7 +42,10 @@ async fn health_check() -> Json { /// Get local system information /// /// Returns static system information like hostname, OS, CPU details -async fn get_system_info(State(_state): State) -> Json { +async fn get_system_info( + _auth: AuthenticatedUser, + State(_state): State, +) -> Json { let collector = LocalSystemCollector::new(); let metrics = collector.collect(); @@ -60,7 +64,10 @@ async fn get_system_info(State(_state): State) -> Json) -> Json { +async fn get_system_metrics( + _auth: AuthenticatedUser, + State(_state): State, +) -> Json { let collector = LocalSystemCollector::new(); let metrics = collector.collect(); diff --git a/control-plane/api-gateway/src/routes/updates.rs b/control-plane/api-gateway/src/routes/updates.rs new file mode 100644 index 0000000..3a150d3 --- /dev/null +++ b/control-plane/api-gateway/src/routes/updates.rs @@ -0,0 +1,285 @@ +use axum::{ + extract::State, + http::StatusCode, + response::{IntoResponse, Response}, + routing::{get, post}, + Json, Router, +}; +use serde::{Deserialize, Serialize}; +use std::process::Command; + +use crate::AppState; + +#[derive(Debug, Serialize, Deserialize)] +pub struct VersionInfo { + pub current_version: String, + pub latest_version: String, + pub update_available: bool, + pub changelog: Option, + pub release_url: String, + pub is_prerelease: bool, + pub latest_beta_version: Option, + pub beta_release_url: Option, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct UpdateRequest { + pub version: String, +} + +#[derive(Debug, Serialize)] +pub struct UpdateResponse { + pub success: bool, + pub message: String, +} + +/// Get current version and check for updates +#[utoipa::path( + get, + path = "/api/updates/check", + responses( + (status = 200, description = "Version information retrieved successfully", body = VersionInfo), + (status = 500, description = "Failed to check for updates") + ), + tag = "Updates" +)] +pub async fn check_updates(State(_state): State) -> Result, AppError> { + let current_version = env!("CARGO_PKG_VERSION").to_string(); + + // Fetch latest release from GitHub + let client = reqwest::Client::builder() + .user_agent("CSF-Core-Updater") + .build() + .map_err(|e| AppError::InternalError(format!("Failed to create HTTP client: {}", e)))?; + + // Get latest stable release + let response = client + .get("https://api.github.com/repos/CS-Foundry/CSF-Core/releases/latest") + .send() + .await + .map_err(|e| AppError::InternalError(format!("Failed to fetch releases: {}", e)))?; + + if !response.status().is_success() { + return Err(AppError::InternalError(format!( + "GitHub API returned status: {}", + response.status() + ))); + } + + let release: GitHubRelease = response + .json() + .await + .map_err(|e| AppError::InternalError(format!("Failed to parse release data: {}", e)))?; + + let latest_version = release.tag_name.trim_start_matches('v').to_string(); + let update_available = version_compare(¤t_version, &latest_version); + + // Check for beta releases + let all_releases_response = client + .get("https://api.github.com/repos/CS-Foundry/CSF-Core/releases") + .send() + .await + .map_err(|e| AppError::InternalError(format!("Failed to fetch all releases: {}", e)))?; + + let all_releases: Vec = all_releases_response + .json() + .await + .map_err(|e| AppError::InternalError(format!("Failed to parse releases data: {}", e)))?; + + // Find latest beta release + let latest_beta = all_releases.iter().find(|r| r.prerelease).map(|r| { + ( + r.tag_name.trim_start_matches('v').to_string(), + r.html_url.clone(), + ) + }); + + Ok(Json(VersionInfo { + current_version, + latest_version: latest_version.clone(), + update_available, + changelog: Some(release.body), + release_url: release.html_url, + is_prerelease: release.prerelease, + latest_beta_version: latest_beta.as_ref().map(|(v, _)| v.clone()), + beta_release_url: latest_beta.map(|(_, url)| url), + })) +} + +/// Trigger update installation +#[utoipa::path( + post, + path = "/api/updates/install", + request_body = UpdateRequest, + responses( + (status = 200, description = "Update initiated successfully", body = UpdateResponse), + (status = 400, description = "Invalid request"), + (status = 500, description = "Failed to start update") + ), + tag = "Updates" +)] +pub async fn install_update( + State(_state): State, + Json(payload): Json, +) -> Result, AppError> { + let current_version = env!("CARGO_PKG_VERSION").to_string(); + + // Safety check: don't downgrade + if !version_compare(¤t_version, &payload.version) { + return Ok(Json(UpdateResponse { + success: false, + message: "Cannot install an older or same version".to_string(), + })); + } + + // Find the update script - try multiple locations + let mut possible_paths: Vec = + vec![std::path::PathBuf::from("/opt/csf-core/scripts/update.sh")]; + + if let Ok(dir) = std::env::current_dir() { + possible_paths.push(dir.join("../scripts/update.sh")); + possible_paths.push(dir.join("scripts/update.sh")); + } + + let script_path = possible_paths + .iter() + .find(|&p: &&std::path::PathBuf| p.exists()) + .ok_or_else(|| { + AppError::InternalError("Update script not found in any expected location".to_string()) + })? + .clone(); + + tracing::info!("Found update script at: {:?}", script_path); + + // Clone version for use in response message + let version_for_message = payload.version.clone(); + + // Start update process in background + tokio::spawn(async move { + match Command::new("sh") + .arg(&script_path) + .arg(&payload.version) + .spawn() + { + Ok(_) => tracing::info!("Update process started for version {}", payload.version), + Err(e) => tracing::error!("Failed to start update process: {}", e), + } + }); + + Ok(Json(UpdateResponse { + success: true, + message: format!( + "Update to version {} initiated. The application will restart shortly.", + version_for_message + ), + })) +} + +/// Get changelog for a specific version +#[utoipa::path( + get, + path = "/api/updates/changelog/{version}", + params( + ("version" = String, Path, description = "Version to get changelog for") + ), + responses( + (status = 200, description = "Changelog retrieved successfully"), + (status = 404, description = "Version not found"), + (status = 500, description = "Failed to fetch changelog") + ), + tag = "Updates" +)] +pub async fn get_changelog( + State(_state): State, + axum::extract::Path(version): axum::extract::Path, +) -> Result, AppError> { + let client = reqwest::Client::builder() + .user_agent("CSF-Core-Updater") + .build() + .map_err(|e| AppError::InternalError(format!("Failed to create HTTP client: {}", e)))?; + + let url = format!( + "https://api.github.com/repos/CS-Foundry/CSF-Core/releases/tags/v{}", + version.trim_start_matches('v') + ); + + let response = client + .get(&url) + .send() + .await + .map_err(|e| AppError::InternalError(format!("Failed to fetch release: {}", e)))?; + + if response.status() == 404 { + return Err(AppError::NotFound(format!("Version {} not found", version))); + } + + if !response.status().is_success() { + return Err(AppError::InternalError(format!( + "GitHub API returned status: {}", + response.status() + ))); + } + + let release: GitHubRelease = response + .json() + .await + .map_err(|e| AppError::InternalError(format!("Failed to parse release data: {}", e)))?; + + Ok(Json(release.body)) +} + +// Helper structs for GitHub API +#[derive(Debug, Deserialize)] +struct GitHubRelease { + tag_name: String, + body: String, + html_url: String, + prerelease: bool, +} + +// Compare versions (returns true if v2 is newer than v1) +fn version_compare(v1: &str, v2: &str) -> bool { + let parse_version = + |v: &str| -> Vec { v.split('.').filter_map(|s| s.parse::().ok()).collect() }; + + let v1_parts = parse_version(v1); + let v2_parts = parse_version(v2); + + for i in 0..v1_parts.len().max(v2_parts.len()) { + let p1 = v1_parts.get(i).copied().unwrap_or(0); + let p2 = v2_parts.get(i).copied().unwrap_or(0); + + if p2 > p1 { + return true; + } else if p2 < p1 { + return false; + } + } + + false +} + +// Error handling +#[derive(Debug)] +pub enum AppError { + InternalError(String), + NotFound(String), +} + +impl IntoResponse for AppError { + fn into_response(self) -> Response { + let (status, message) = match self { + AppError::InternalError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg), + AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg), + }; + + (status, Json(serde_json::json!({ "error": message }))).into_response() + } +} + +pub fn router() -> Router { + Router::new() + .route("/updates/check", get(check_updates)) + .route("/updates/install", post(install_update)) + .route("/updates/changelog/:version", get(get_changelog)) +} diff --git a/backend/src/routes/users.rs b/control-plane/api-gateway/src/routes/users.rs similarity index 100% rename from backend/src/routes/users.rs rename to control-plane/api-gateway/src/routes/users.rs diff --git a/backend/src/self_monitor.rs b/control-plane/api-gateway/src/self_monitor.rs similarity index 100% rename from backend/src/self_monitor.rs rename to control-plane/api-gateway/src/self_monitor.rs diff --git a/backend/src/system_collector.rs b/control-plane/api-gateway/src/system_collector.rs similarity index 100% rename from backend/src/system_collector.rs rename to control-plane/api-gateway/src/system_collector.rs diff --git a/backend/src/utils/mod.rs b/control-plane/api-gateway/src/utils/mod.rs similarity index 100% rename from backend/src/utils/mod.rs rename to control-plane/api-gateway/src/utils/mod.rs diff --git a/backend/src/utils/router_ext.rs b/control-plane/api-gateway/src/utils/router_ext.rs similarity index 100% rename from backend/src/utils/router_ext.rs rename to control-plane/api-gateway/src/utils/router_ext.rs diff --git a/control-plane/failover-controller/Cargo.toml b/control-plane/failover-controller/Cargo.toml new file mode 100644 index 0000000..0071c3d --- /dev/null +++ b/control-plane/failover-controller/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "failover-controller" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[[bin]] +name = "failover-controller" +path = "src/main.rs" + +[dependencies] +tokio = { version = "1.43", features = ["full"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +anyhow = "1.0" diff --git a/control-plane/failover-controller/Dockerfile.dev b/control-plane/failover-controller/Dockerfile.dev new file mode 100644 index 0000000..0f3737e --- /dev/null +++ b/control-plane/failover-controller/Dockerfile.dev @@ -0,0 +1,38 @@ +# Development Dockerfile for Failover Controller +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && cargo install cargo-watch --version 7.8.0 --locked \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY agent/Cargo.toml ./agent/ +COPY cli/Cargo.toml ./cli/ +COPY control-plane/api-gateway/Cargo.toml ./control-plane/api-gateway/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ +COPY shared/Cargo.toml ./shared/ +COPY entity/Cargo.toml ./entity/ +COPY migration/Cargo.toml ./migration/ + +# Copy service and dependencies +COPY control-plane/failover-controller/ ./control-plane/failover-controller/ +COPY shared/ ./shared/ +COPY entity/ ./entity/ +COPY migration/ ./migration/ + +# Pre-build dependencies +RUN cargo build --bin failover-controller + +CMD ["cargo", "watch", "-x", "run --bin failover-controller"] diff --git a/control-plane/failover-controller/src/main.rs b/control-plane/failover-controller/src/main.rs new file mode 100644 index 0000000..0197701 --- /dev/null +++ b/control-plane/failover-controller/src/main.rs @@ -0,0 +1,26 @@ +use tracing::{info, warn}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Initialize logger + tracing_subscriber::fmt() + .with_target(false) + .with_thread_ids(true) + .with_level(true) + .init(); + + info!("πŸ›‘οΈ Failover Controller Service starting..."); + info!("βœ… Failover Controller initialized"); + + // Demo: Simulated health monitoring loop + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(20)); + + loop { + interval.tick().await; + info!("πŸ” Monitoring node health..."); + info!(" - Checking heartbeat signals"); + info!(" - Analyzing failure patterns"); + info!(" - Preparing recovery strategies"); + warn!(" ⚠️ Demo mode: No actual failover performed"); + } +} diff --git a/control-plane/registry/Cargo.toml b/control-plane/registry/Cargo.toml new file mode 100644 index 0000000..41f156a --- /dev/null +++ b/control-plane/registry/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "registry" +version.workspace = true +edition.workspace = true +license.workspace = true + +[[bin]] +name = "registry" +path = "src/main.rs" + +[dependencies] +# Internal dependencies +shared = { path = "../shared/shared" } + +# Async runtime +tokio = { workspace = true } + +# Logging +tracing = { workspace = true } +tracing-subscriber = { workspace = true } + +# Utilities +dotenvy = { workspace = true } +anyhow = { workspace = true } diff --git a/control-plane/registry/Dockerfile.dev b/control-plane/registry/Dockerfile.dev new file mode 100644 index 0000000..063d148 --- /dev/null +++ b/control-plane/registry/Dockerfile.dev @@ -0,0 +1,38 @@ +# Development Dockerfile for Registry +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && cargo install cargo-watch --version 7.8.0 --locked \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY agent/Cargo.toml ./agent/ +COPY cli/Cargo.toml ./cli/ +COPY control-plane/api-gateway/Cargo.toml ./control-plane/api-gateway/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ +COPY shared/Cargo.toml ./shared/ +COPY entity/Cargo.toml ./entity/ +COPY migration/Cargo.toml ./migration/ + +# Copy service and dependencies +COPY control-plane/registry/ ./control-plane/registry/ +COPY shared/ ./shared/ +COPY entity/ ./entity/ +COPY migration/ ./migration/ + +# Pre-build dependencies +RUN cargo build --bin registry + +CMD ["cargo", "watch", "-x", "run --bin registry"] diff --git a/control-plane/registry/src/main.rs b/control-plane/registry/src/main.rs new file mode 100644 index 0000000..e82826e --- /dev/null +++ b/control-plane/registry/src/main.rs @@ -0,0 +1,27 @@ +use tracing::{info, warn}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Initialize logger + tracing_subscriber::fmt() + .with_target(false) + .with_thread_ids(true) + .with_level(true) + .init(); + + info!("πŸ“‹ Registry Service starting..."); + info!("βœ… Registry initialized"); + + // Demo: Simulated registry management loop + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(15)); + + loop { + interval.tick().await; + info!("πŸ“ Managing node registry..."); + info!(" - Tracking registered nodes"); + info!(" - Updating node metadata"); + info!(" - Monitoring node health status"); + info!(" - Pruning stale entries"); + warn!(" ⚠️ Demo mode: No actual registry updates performed"); + } +} diff --git a/control-plane/scheduler/Cargo.toml b/control-plane/scheduler/Cargo.toml new file mode 100644 index 0000000..205e103 --- /dev/null +++ b/control-plane/scheduler/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "scheduler" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[[bin]] +name = "scheduler" +path = "src/main.rs" + +[dependencies] +tokio = { version = "1.43", features = ["full"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +anyhow = "1.0" diff --git a/control-plane/scheduler/Dockerfile.dev b/control-plane/scheduler/Dockerfile.dev new file mode 100644 index 0000000..41ea6b5 --- /dev/null +++ b/control-plane/scheduler/Dockerfile.dev @@ -0,0 +1,38 @@ +# Development Dockerfile for Scheduler +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && cargo install cargo-watch --version 7.8.0 --locked \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY agent/Cargo.toml ./agent/ +COPY cli/Cargo.toml ./cli/ +COPY control-plane/api-gateway/Cargo.toml ./control-plane/api-gateway/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ +COPY shared/Cargo.toml ./shared/ +COPY entity/Cargo.toml ./entity/ +COPY migration/Cargo.toml ./migration/ + +# Copy service and dependencies +COPY control-plane/scheduler/ ./control-plane/scheduler/ +COPY shared/ ./shared/ +COPY entity/ ./entity/ +COPY migration/ ./migration/ + +# Pre-build dependencies +RUN cargo build --bin scheduler + +CMD ["cargo", "watch", "-x", "run --bin scheduler"] diff --git a/control-plane/scheduler/src/main.rs b/control-plane/scheduler/src/main.rs new file mode 100644 index 0000000..79e67e5 --- /dev/null +++ b/control-plane/scheduler/src/main.rs @@ -0,0 +1,26 @@ +use tracing::{info, warn}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Initialize logger + tracing_subscriber::fmt() + .with_target(false) + .with_thread_ids(true) + .with_level(true) + .init(); + + info!("πŸ—“οΈ Scheduler Service starting..."); + info!("βœ… Scheduler initialized"); + + // Demo: Simulated scheduler loop + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(30)); + + loop { + interval.tick().await; + info!("πŸ”„ Running scheduling cycle..."); + info!(" - Checking resource availability"); + info!(" - Analyzing workload distribution"); + info!(" - Optimizing VM placement"); + warn!(" ⚠️ Demo mode: No actual scheduling performed"); + } +} diff --git a/control-plane/sdn-controller/Cargo.toml b/control-plane/sdn-controller/Cargo.toml new file mode 100644 index 0000000..3e9b372 --- /dev/null +++ b/control-plane/sdn-controller/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "sdn-controller" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[[bin]] +name = "sdn-controller" +path = "src/main.rs" + +[dependencies] +tokio = { version = "1.43", features = ["full"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +anyhow = "1.0" diff --git a/control-plane/sdn-controller/Dockerfile.dev b/control-plane/sdn-controller/Dockerfile.dev new file mode 100644 index 0000000..6aeaf3c --- /dev/null +++ b/control-plane/sdn-controller/Dockerfile.dev @@ -0,0 +1,38 @@ +# Development Dockerfile for SDN Controller +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && cargo install cargo-watch --version 7.8.0 --locked \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY agent/Cargo.toml ./agent/ +COPY cli/Cargo.toml ./cli/ +COPY control-plane/api-gateway/Cargo.toml ./control-plane/api-gateway/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ +COPY shared/Cargo.toml ./shared/ +COPY entity/Cargo.toml ./entity/ +COPY migration/Cargo.toml ./migration/ + +# Copy service and dependencies +COPY control-plane/sdn-controller/ ./control-plane/sdn-controller/ +COPY shared/ ./shared/ +COPY entity/ ./entity/ +COPY migration/ ./migration/ + +# Pre-build dependencies +RUN cargo build --bin sdn-controller + +CMD ["cargo", "watch", "-x", "run --bin sdn-controller"] diff --git a/control-plane/sdn-controller/src/main.rs b/control-plane/sdn-controller/src/main.rs new file mode 100644 index 0000000..b829c47 --- /dev/null +++ b/control-plane/sdn-controller/src/main.rs @@ -0,0 +1,27 @@ +use tracing::{info, warn}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Initialize logger + tracing_subscriber::fmt() + .with_target(false) + .with_thread_ids(true) + .with_level(true) + .init(); + + info!("🌐 SDN Controller Service starting..."); + info!("βœ… SDN Controller initialized"); + + // Demo: Simulated network management loop + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(25)); + + loop { + interval.tick().await; + info!("πŸ”Œ Managing network infrastructure..."); + info!(" - Configuring VXLAN tunnels"); + info!(" - Managing IP address allocation (IPAM)"); + info!(" - Updating firewall rules"); + info!(" - Optimizing routing tables"); + warn!(" ⚠️ Demo mode: No actual network changes applied"); + } +} diff --git a/control-plane/shared/Cargo.toml b/control-plane/shared/Cargo.toml new file mode 100644 index 0000000..072d6a6 --- /dev/null +++ b/control-plane/shared/Cargo.toml @@ -0,0 +1,14 @@ +[workspace] +resolver = "2" +members = [ + "entity", + "migration", + "shared", +] + +[workspace.package] +version = "0.2.2" +edition = "2021" +authors = ["CS-Foundry"] +license = "SEE LICENSE IN LICENSE" +repository = "https://github.com/CS-Foundry/CSF-Core" diff --git a/control-plane/shared/entity/Cargo.toml b/control-plane/shared/entity/Cargo.toml new file mode 100644 index 0000000..3fa3ee9 --- /dev/null +++ b/control-plane/shared/entity/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "entity" +version.workspace = true +edition.workspace = true +license.workspace = true + +[lib] +path = "src/lib.rs" + +[dependencies] +sea-orm = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +uuid = { workspace = true } +chrono = { workspace = true } +utoipa = { workspace = true } diff --git a/backend/entity/src/entities/agent_metrics.rs b/control-plane/shared/entity/src/entities/agent_metrics.rs similarity index 100% rename from backend/entity/src/entities/agent_metrics.rs rename to control-plane/shared/entity/src/entities/agent_metrics.rs diff --git a/backend/entity/src/entities/agents.rs b/control-plane/shared/entity/src/entities/agents.rs similarity index 100% rename from backend/entity/src/entities/agents.rs rename to control-plane/shared/entity/src/entities/agents.rs diff --git a/backend/entity/src/entities/config.rs b/control-plane/shared/entity/src/entities/config.rs similarity index 100% rename from backend/entity/src/entities/config.rs rename to control-plane/shared/entity/src/entities/config.rs diff --git a/backend/entity/src/entities/docker_resources.rs b/control-plane/shared/entity/src/entities/docker_resources.rs similarity index 100% rename from backend/entity/src/entities/docker_resources.rs rename to control-plane/shared/entity/src/entities/docker_resources.rs diff --git a/backend/entity/src/entities/expenses.rs b/control-plane/shared/entity/src/entities/expenses.rs similarity index 100% rename from backend/entity/src/entities/expenses.rs rename to control-plane/shared/entity/src/entities/expenses.rs diff --git a/backend/entity/src/entities/invalid_jwt.rs b/control-plane/shared/entity/src/entities/invalid_jwt.rs similarity index 100% rename from backend/entity/src/entities/invalid_jwt.rs rename to control-plane/shared/entity/src/entities/invalid_jwt.rs diff --git a/backend/entity/src/entities/key.rs b/control-plane/shared/entity/src/entities/key.rs similarity index 100% rename from backend/entity/src/entities/key.rs rename to control-plane/shared/entity/src/entities/key.rs diff --git a/backend/entity/src/entities/marketplace_templates.rs b/control-plane/shared/entity/src/entities/marketplace_templates.rs similarity index 100% rename from backend/entity/src/entities/marketplace_templates.rs rename to control-plane/shared/entity/src/entities/marketplace_templates.rs diff --git a/backend/entity/src/entities/mod.rs b/control-plane/shared/entity/src/entities/mod.rs similarity index 100% rename from backend/entity/src/entities/mod.rs rename to control-plane/shared/entity/src/entities/mod.rs diff --git a/backend/entity/src/entities/organization.rs b/control-plane/shared/entity/src/entities/organization.rs similarity index 100% rename from backend/entity/src/entities/organization.rs rename to control-plane/shared/entity/src/entities/organization.rs diff --git a/backend/entity/src/entities/permission.rs b/control-plane/shared/entity/src/entities/permission.rs similarity index 100% rename from backend/entity/src/entities/permission.rs rename to control-plane/shared/entity/src/entities/permission.rs diff --git a/backend/entity/src/entities/resource_groups.rs b/control-plane/shared/entity/src/entities/resource_groups.rs similarity index 100% rename from backend/entity/src/entities/resource_groups.rs rename to control-plane/shared/entity/src/entities/resource_groups.rs diff --git a/backend/entity/src/entities/role.rs b/control-plane/shared/entity/src/entities/role.rs similarity index 100% rename from backend/entity/src/entities/role.rs rename to control-plane/shared/entity/src/entities/role.rs diff --git a/backend/entity/src/entities/role_permission.rs b/control-plane/shared/entity/src/entities/role_permission.rs similarity index 100% rename from backend/entity/src/entities/role_permission.rs rename to control-plane/shared/entity/src/entities/role_permission.rs diff --git a/backend/entity/src/entities/subscription.rs b/control-plane/shared/entity/src/entities/subscription.rs similarity index 100% rename from backend/entity/src/entities/subscription.rs rename to control-plane/shared/entity/src/entities/subscription.rs diff --git a/backend/entity/src/entities/user.rs b/control-plane/shared/entity/src/entities/user.rs similarity index 100% rename from backend/entity/src/entities/user.rs rename to control-plane/shared/entity/src/entities/user.rs diff --git a/backend/entity/src/entities/user_organization.rs b/control-plane/shared/entity/src/entities/user_organization.rs similarity index 100% rename from backend/entity/src/entities/user_organization.rs rename to control-plane/shared/entity/src/entities/user_organization.rs diff --git a/backend/entity/src/lib.rs b/control-plane/shared/entity/src/lib.rs similarity index 100% rename from backend/entity/src/lib.rs rename to control-plane/shared/entity/src/lib.rs diff --git a/control-plane/shared/entity/src/main.rs b/control-plane/shared/entity/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/control-plane/shared/entity/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/control-plane/shared/migration/Cargo.toml b/control-plane/shared/migration/Cargo.toml new file mode 100644 index 0000000..8251be3 --- /dev/null +++ b/control-plane/shared/migration/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "migration" +version.workspace = true +edition.workspace = true +license.workspace = true +publish = false + +[lib] +name = "migration" +path = "src/lib.rs" + +[dependencies] +async-std = { version = "1", features = ["attributes", "tokio1"] } +sea-orm-migration = { workspace = true } diff --git a/backend/migration/src/lib.rs b/control-plane/shared/migration/src/lib.rs similarity index 100% rename from backend/migration/src/lib.rs rename to control-plane/shared/migration/src/lib.rs diff --git a/backend/migration/src/m20251026_150747_key.rs b/control-plane/shared/migration/src/m20251026_150747_key.rs similarity index 100% rename from backend/migration/src/m20251026_150747_key.rs rename to control-plane/shared/migration/src/m20251026_150747_key.rs diff --git a/backend/migration/src/m20251026_150819_invalid_jwt.rs b/control-plane/shared/migration/src/m20251026_150819_invalid_jwt.rs similarity index 100% rename from backend/migration/src/m20251026_150819_invalid_jwt.rs rename to control-plane/shared/migration/src/m20251026_150819_invalid_jwt.rs diff --git a/backend/migration/src/m20251026_150828_user.rs b/control-plane/shared/migration/src/m20251026_150828_user.rs similarity index 100% rename from backend/migration/src/m20251026_150828_user.rs rename to control-plane/shared/migration/src/m20251026_150828_user.rs diff --git a/backend/migration/src/m20251026_151103_config.rs b/control-plane/shared/migration/src/m20251026_151103_config.rs similarity index 100% rename from backend/migration/src/m20251026_151103_config.rs rename to control-plane/shared/migration/src/m20251026_151103_config.rs diff --git a/backend/migration/src/m20251030_192944_expenses.rs b/control-plane/shared/migration/src/m20251030_192944_expenses.rs similarity index 100% rename from backend/migration/src/m20251030_192944_expenses.rs rename to control-plane/shared/migration/src/m20251030_192944_expenses.rs diff --git a/backend/migration/src/m20251101_200000_subscriptions.rs b/control-plane/shared/migration/src/m20251101_200000_subscriptions.rs similarity index 100% rename from backend/migration/src/m20251101_200000_subscriptions.rs rename to control-plane/shared/migration/src/m20251101_200000_subscriptions.rs diff --git a/backend/migration/src/m20251215_175420_add_user_2fa_fields.rs b/control-plane/shared/migration/src/m20251215_175420_add_user_2fa_fields.rs similarity index 100% rename from backend/migration/src/m20251215_175420_add_user_2fa_fields.rs rename to control-plane/shared/migration/src/m20251215_175420_add_user_2fa_fields.rs diff --git a/backend/migration/src/m20251215_180000_add_rbac_tables.rs b/control-plane/shared/migration/src/m20251215_180000_add_rbac_tables.rs similarity index 100% rename from backend/migration/src/m20251215_180000_add_rbac_tables.rs rename to control-plane/shared/migration/src/m20251215_180000_add_rbac_tables.rs diff --git a/backend/migration/src/m20251216_190000_add_agents_and_metrics.rs b/control-plane/shared/migration/src/m20251216_190000_add_agents_and_metrics.rs similarity index 100% rename from backend/migration/src/m20251216_190000_add_agents_and_metrics.rs rename to control-plane/shared/migration/src/m20251216_190000_add_agents_and_metrics.rs diff --git a/backend/migration/src/m20251228_120000_add_resource_groups.rs b/control-plane/shared/migration/src/m20251228_120000_add_resource_groups.rs similarity index 100% rename from backend/migration/src/m20251228_120000_add_resource_groups.rs rename to control-plane/shared/migration/src/m20251228_120000_add_resource_groups.rs diff --git a/backend/migration/src/m20251228_140000_add_docker_resources.rs b/control-plane/shared/migration/src/m20251228_140000_add_docker_resources.rs similarity index 100% rename from backend/migration/src/m20251228_140000_add_docker_resources.rs rename to control-plane/shared/migration/src/m20251228_140000_add_docker_resources.rs diff --git a/backend/migration/src/main.rs b/control-plane/shared/migration/src/main.rs similarity index 100% rename from backend/migration/src/main.rs rename to control-plane/shared/migration/src/main.rs diff --git a/control-plane/shared/shared/Cargo.toml b/control-plane/shared/shared/Cargo.toml new file mode 100644 index 0000000..d8f203b --- /dev/null +++ b/control-plane/shared/shared/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "shared" +version.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +# Internal dependencies +migration = { path = "../migration" } + +# Database +sea-orm = { workspace = true } +sea-orm-migration = { workspace = true } + +# Async +tokio = { workspace = true } +async-trait = { workspace = true } + +# Logging +tracing = { workspace = true } +tracing-subscriber = { workspace = true } + +# Utilities +dotenvy = { workspace = true } +anyhow = { workspace = true } +thiserror = { workspace = true } + +# Serialization +serde = { workspace = true } diff --git a/control-plane/shared/shared/src/db.rs b/control-plane/shared/shared/src/db.rs new file mode 100644 index 0000000..f2f2de0 --- /dev/null +++ b/control-plane/shared/shared/src/db.rs @@ -0,0 +1,37 @@ +use migration::{Migrator, MigratorTrait}; +use sea_orm::{Database, DbConn, DbErr}; +use std::env; + +/// Establish a database connection and run migrations +/// +/// This function: +/// 1. Reads DATABASE_URL from environment +/// 2. Connects to the PostgreSQL database +/// 3. Runs all pending migrations +/// +/// # Errors +/// Returns DbErr if connection or migration fails +pub async fn establish_connection() -> Result { + let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); + + tracing::info!("Connecting to PostgreSQL database..."); + let db_conn = Database::connect(&database_url).await?; + + // Run pending migrations + tracing::info!("Running database migrations..."); + Migrator::up(&db_conn, None).await?; + tracing::info!("Database migrations completed successfully"); + + Ok(db_conn) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_db_url_required() { + // This would panic if DATABASE_URL is not set + // In real tests, you'd mock the environment + } +} diff --git a/control-plane/shared/shared/src/lib.rs b/control-plane/shared/shared/src/lib.rs new file mode 100644 index 0000000..42ab76b --- /dev/null +++ b/control-plane/shared/shared/src/lib.rs @@ -0,0 +1,5 @@ +pub mod db; +pub mod logger; + +pub use db::establish_connection; +pub use logger::init_logger; diff --git a/control-plane/shared/shared/src/logger.rs b/control-plane/shared/shared/src/logger.rs new file mode 100644 index 0000000..73fec1a --- /dev/null +++ b/control-plane/shared/shared/src/logger.rs @@ -0,0 +1,24 @@ +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; + +/// Initialize the tracing logger with environment filter support +/// +/// Usage: +/// - Set RUST_LOG env variable to control log level (e.g., RUST_LOG=debug) +/// - Default level is "info" +pub fn init_logger() { + tracing_subscriber::registry() + .with(EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"))) + .with(tracing_subscriber::fmt::layer()) + .init(); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_logger_init() { + // This test just verifies that logger initialization doesn't panic + init_logger(); + } +} diff --git a/control-plane/shared/shared/src/main.rs b/control-plane/shared/shared/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/control-plane/shared/shared/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/control-plane/volume-manager/Cargo.toml b/control-plane/volume-manager/Cargo.toml new file mode 100644 index 0000000..a56e773 --- /dev/null +++ b/control-plane/volume-manager/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "volume-manager" +version.workspace = true +edition.workspace = true +license.workspace = true + +[[bin]] +name = "volume-manager" +path = "src/main.rs" + +[dependencies] +# Internal dependencies +shared = { path = "../shared/shared" } + +# Async runtime +tokio = { workspace = true } + +# Logging +tracing = { workspace = true } +tracing-subscriber = { workspace = true } + +# Utilities +dotenvy = { workspace = true } +anyhow = { workspace = true } diff --git a/control-plane/volume-manager/Dockerfile.dev b/control-plane/volume-manager/Dockerfile.dev new file mode 100644 index 0000000..1f2198e --- /dev/null +++ b/control-plane/volume-manager/Dockerfile.dev @@ -0,0 +1,38 @@ +# Development Dockerfile for Volume Manager +FROM rust:latest + +WORKDIR /app + +# Install development dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && cargo install cargo-watch --version 7.8.0 --locked \ + && rm -rf /var/lib/apt/lists/* + +# Copy workspace configuration +COPY Cargo.toml Cargo.lock ./ + +# Copy manifests for workspace members +COPY agent/Cargo.toml ./agent/ +COPY cli/Cargo.toml ./cli/ +COPY control-plane/api-gateway/Cargo.toml ./control-plane/api-gateway/ +COPY control-plane/scheduler/Cargo.toml ./control-plane/scheduler/ +COPY control-plane/failover-controller/Cargo.toml ./control-plane/failover-controller/ +COPY control-plane/sdn-controller/Cargo.toml ./control-plane/sdn-controller/ +COPY control-plane/volume-manager/Cargo.toml ./control-plane/volume-manager/ +COPY control-plane/registry/Cargo.toml ./control-plane/registry/ +COPY shared/Cargo.toml ./shared/ +COPY entity/Cargo.toml ./entity/ +COPY migration/Cargo.toml ./migration/ + +# Copy service and dependencies +COPY control-plane/volume-manager/ ./control-plane/volume-manager/ +COPY shared/ ./shared/ +COPY entity/ ./entity/ +COPY migration/ ./migration/ + +# Pre-build dependencies +RUN cargo build --bin volume-manager + +CMD ["cargo", "watch", "-x", "run --bin volume-manager"] diff --git a/control-plane/volume-manager/src/main.rs b/control-plane/volume-manager/src/main.rs new file mode 100644 index 0000000..779a988 --- /dev/null +++ b/control-plane/volume-manager/src/main.rs @@ -0,0 +1,27 @@ +use tracing::{info, warn}; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Initialize logger + tracing_subscriber::fmt() + .with_target(false) + .with_thread_ids(true) + .with_level(true) + .init(); + + info!("πŸ’Ύ Volume Manager Service starting..."); + info!("βœ… Volume Manager initialized"); + + // Demo: Simulated storage management loop + let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(35)); + + loop { + interval.tick().await; + info!("πŸ“¦ Managing storage volumes..."); + info!(" - Monitoring Ceph cluster health"); + info!(" - Creating/managing RBD volumes"); + info!(" - Processing snapshot requests"); + info!(" - Verifying encryption status"); + warn!(" ⚠️ Demo mode: No actual volume operations performed"); + } +} diff --git a/csf-core.service b/csf-core.service deleted file mode 100644 index a69a044..0000000 --- a/csf-core.service +++ /dev/null @@ -1,57 +0,0 @@ -[Unit] -Description=CSF Core Backend and Frontend Service -Documentation=https://github.com/CS-Foundry/CSF-Core -After=network.target postgresql.service -Wants=postgresql.service - -[Service] -Type=forking -User=csf-core -Group=csf-core -WorkingDirectory=/opt/csf-core - -# Load environment from config file (if exists) -EnvironmentFile=-/opt/csf-core/config.env - -# Default environment variables (can be overridden in config.env) -Environment="DATABASE_URL=postgres://csf_core:password@localhost/csf_core" -Environment="JWT_SECRET=change-this-in-production" -Environment="RUST_LOG=info" -Environment="NODE_ENV=production" -Environment="PORT=3000" -Environment="FRONTEND_URL=http://localhost:3000" -Environment="ORIGIN=http://localhost:8000" - -# Security settings -PrivateTmp=true -ProtectSystem=strict -ProtectHome=true -NoNewPrivileges=false -ReadWritePaths=/opt/csf-core -ReadWritePaths=/var/lib/csf-core -ReadWritePaths=/var/log/csf-core -ReadWritePaths=/tmp -ReadWritePaths=/var/tmp -SupplementaryGroups=docker - -# Startup: Use unified startup script -ExecStart=/opt/csf-core/start.sh - -# Process management -Restart=on-failure -RestartSec=10 -KillMode=mixed -KillSignal=SIGTERM -TimeoutStartSec=60 -TimeoutStopSec=30 - -# Resource limits -LimitNOFILE=65536 -LimitNPROC=4096 - -# Logging -StandardOutput=append:/var/log/csf-core/csf-core.log -StandardError=append:/var/log/csf-core/csf-core-error.log - -[Install] -WantedBy=multi-user.target diff --git a/csf-core.sudoers b/csf-core.sudoers deleted file mode 100644 index 41122f4..0000000 --- a/csf-core.sudoers +++ /dev/null @@ -1,32 +0,0 @@ -# Sudoers configuration for CSF-Core -# This file should be placed in /etc/sudoers.d/csf-core -# File permissions must be 0440 (chmod 0440 /etc/sudoers.d/csf-core) - -# Allow csf-core user to run update script without password (with nohup for detachment) -csf-core ALL=(ALL) NOPASSWD: /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup /usr/bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/nohup sudo /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /usr/bin/sudo /usr/bin/nohup /bin/bash /opt/csf-core/scripts/update.sh* -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl daemon-reload -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl start csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl stop csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl restart csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl status csf-core.service -csf-core ALL=(ALL) NOPASSWD: /bin/systemctl is-active csf-core.service - -# Additional commands that update script may need -csf-core ALL=(ALL) NOPASSWD: /bin/chown -R csf-core\:csf-core /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/cp -rp /opt/csf-core* * -csf-core ALL=(ALL) NOPASSWD: /bin/mv * /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -rf /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -rf /tmp/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -rf /var/tmp/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/rm -f /tmp/csf-core-update-status.json -csf-core ALL=(ALL) NOPASSWD: /bin/mkdir -p * -csf-core ALL=(ALL) NOPASSWD: /bin/tar -xzf * -C /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/chmod +x /opt/csf-core* -csf-core ALL=(ALL) NOPASSWD: /bin/chmod 644 /tmp/csf-core-update-status.json -csf-core ALL=(ALL) NOPASSWD: /usr/bin/rsync -a /opt/csf-core* * diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index ff2f77d..ba18e5d 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,33 +1,14 @@ -version: '3.8' - services: - frontend-dev: - build: - context: ./frontend - dockerfile: Dockerfile.dev - ports: - - "3000:3000" - env_file: - - .env - volumes: - - ./frontend:/app - - /app/node_modules - environment: - - NODE_ENV=development - - JWT_SECRET=${JWT_SECRET} - - PUBLIC_API_BASE_URL=http://localhost:8000/api - command: sh -c "npm install && JWT_SECRET=${JWT_SECRET} npm run dev -- --host 0.0.0.0 --port 3000" - depends_on: - - backend-dev - + # PostgreSQL Database postgres: image: postgres:16-alpine + container_name: csf-postgres-dev + environment: + POSTGRES_USER: csf_user + POSTGRES_PASSWORD: csf_password + POSTGRES_DB: csf_core ports: - "5432:5432" - environment: - - POSTGRES_USER=csf_user - - POSTGRES_PASSWORD=csf_password - - POSTGRES_DB=csf_core volumes: - postgres_data:/var/lib/postgresql/data healthcheck: @@ -35,30 +16,259 @@ services: interval: 10s timeout: 5s retries: 5 + networks: + - csf-network - backend-dev: - env_file: - - .env + # API Gateway + api-gateway: build: - context: ./backend - dockerfile: Dockerfile.dev + context: . + dockerfile: control-plane/api-gateway/Dockerfile.dev + container_name: csf-api-gateway-dev + environment: + DATABASE_URL: postgres://csf_user:csf_password@postgres:5432/csf_core + RUST_LOG: debug + JWT_SECRET: ${JWT_SECRET:-dev_jwt_secret_change_in_production} + RSA_KEY_SIZE: "2048" ports: - "8000:8000" + depends_on: + postgres: + condition: service_healthy volumes: - - ./backend:/usr/src/app - - cargo_registry:/usr/local/cargo/registry - - cargo_target:/usr/src/app/target + - ./control-plane/api-gateway:/app/control-plane/api-gateway + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_api_gateway:/app/target + networks: + - csf-network + command: cargo watch -x "run --bin api-gateway" + restart: unless-stopped + + # Scheduler Service + scheduler: + build: + context: . + dockerfile: control-plane/scheduler/Dockerfile.dev + container_name: csf-scheduler-dev environment: - - DATABASE_URL=postgres://csf_user:csf_password@postgres:5432/csf_core - - CARGO_HOME=/usr/local/cargo - - JWT_SECRET=${JWT_SECRET} - - RUST_LOG=debug - command: cargo watch -x run + DATABASE_URL: postgres://csf_user:csf_password@postgres:5432/csf_core + RUST_LOG: debug depends_on: postgres: condition: service_healthy + api-gateway: + condition: service_started + volumes: + - ./control-plane/scheduler:/app/control-plane/scheduler + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_scheduler:/app/target + networks: + - csf-network + command: cargo watch -x "run --bin scheduler" + restart: unless-stopped + + # Failover Controller Service + failover-controller: + build: + context: . + dockerfile: control-plane/failover-controller/Dockerfile.dev + container_name: csf-failover-controller-dev + environment: + DATABASE_URL: postgres://csf_user:csf_password@postgres:5432/csf_core + RUST_LOG: debug + depends_on: + postgres: + condition: service_healthy + api-gateway: + condition: service_started + volumes: + - ./control-plane/failover-controller:/app/control-plane/failover-controller + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_failover:/app/target + networks: + - csf-network + command: cargo watch -x "run --bin failover-controller" + restart: unless-stopped + + # SDN Controller Service + sdn-controller: + build: + context: . + dockerfile: control-plane/sdn-controller/Dockerfile.dev + container_name: csf-sdn-controller-dev + environment: + DATABASE_URL: postgres://csf_user:csf_password@postgres:5432/csf_core + RUST_LOG: debug + depends_on: + postgres: + condition: service_healthy + api-gateway: + condition: service_started + volumes: + - ./control-plane/sdn-controller:/app/control-plane/sdn-controller + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_sdn:/app/target + networks: + - csf-network + command: cargo watch -x "run --bin sdn-controller" + restart: unless-stopped + + # Volume Manager Service + volume-manager: + build: + context: . + dockerfile: control-plane/volume-manager/Dockerfile.dev + container_name: csf-volume-manager-dev + environment: + DATABASE_URL: postgres://csf_user:csf_password@postgres:5432/csf_core + RUST_LOG: debug + depends_on: + postgres: + condition: service_healthy + api-gateway: + condition: service_started + volumes: + - ./control-plane/volume-manager:/app/control-plane/volume-manager + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_volume:/app/target + networks: + - csf-network + command: cargo watch -x "run --bin volume-manager" + restart: unless-stopped + + # Registry Service + registry: + build: + context: . + dockerfile: control-plane/registry/Dockerfile.dev + container_name: csf-registry-dev + environment: + DATABASE_URL: postgres://csf_user:csf_password@postgres:5432/csf_core + RUST_LOG: debug + depends_on: + postgres: + condition: service_healthy + api-gateway: + condition: service_started + volumes: + - ./control-plane/registry:/app/control-plane/registry + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_registry:/app/target + networks: + - csf-network + command: cargo watch -x "run --bin registry" + restart: unless-stopped + + # Agent + agent: + build: + context: . + dockerfile: agent/Dockerfile.dev + container_name: csf-agent-dev + environment: + CONTROL_PLANE_URL: http://api-gateway:8000 + RUST_LOG: debug + depends_on: + - api-gateway + volumes: + - ./agent:/app/agent + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_agent:/app/target + - /var/run/docker.sock:/var/run/docker.sock + networks: + - csf-network + command: cargo watch -x "run --bin agent" + restart: unless-stopped + + # CLI (runs once for testing) + cli: + build: + context: . + dockerfile: cli/Dockerfile.dev + container_name: csf-cli-dev + environment: + CONTROL_PLANE_URL: http://api-gateway:8000 + RUST_LOG: info + depends_on: + - api-gateway + volumes: + - ./cli:/app/cli + - ./shared:/app/shared + - ./Cargo.toml:/app/Cargo.toml + - ./Cargo.lock:/app/Cargo.lock + - cargo_cache:/usr/local/cargo/registry + - cargo_target_cli:/app/target + networks: + - csf-network + command: cargo run --bin csf + profiles: + - tools + + # Frontend Development Server + frontend-dev: + build: + context: ./frontend + dockerfile: Dockerfile.dev + container_name: csf-frontend-dev + ports: + - "3000:3000" + environment: + NODE_ENV: development + JWT_SECRET: ${JWT_SECRET:-dev_jwt_secret} + PUBLIC_API_BASE_URL: http://localhost:8000/api + volumes: + - ./frontend:/app + - /app/node_modules + command: sh -c "npm install && JWT_SECRET=${JWT_SECRET} npm run dev -- --host 0.0.0.0 --port 3000" + depends_on: + - api-gateway + networks: + - csf-network volumes: - cargo_registry: - cargo_target: postgres_data: + driver: local + cargo_cache: + driver: local + cargo_target_api_gateway: + driver: local + cargo_target_scheduler: + driver: local + cargo_target_failover: + driver: local + cargo_target_sdn: + driver: local + cargo_target_volume: + driver: local + cargo_target_registry: + driver: local + cargo_target_agent: + driver: local + cargo_target_cli: + driver: local + +networks: + csf-network: + driver: bridge + diff --git a/docker-compose.local-backend.yml b/docker-compose.local-backend.yml deleted file mode 100644 index d2eb26a..0000000 --- a/docker-compose.local-backend.yml +++ /dev/null @@ -1,47 +0,0 @@ -version: '3.8' - -# Use this compose file when running the backend locally (outside Docker) -# This will only start the frontend and postgres containers -# Run: docker-compose -f docker-compose.local-backend.yml up -d - -services: - frontend-dev: - build: - context: ./frontend - dockerfile: Dockerfile.dev - ports: - - "3000:3000" - env_file: - - .env - volumes: - - ./frontend:/app - - /app/node_modules - environment: - - NODE_ENV=development - - JWT_SECRET=${JWT_SECRET} - # Point to host.docker.internal for backend running on host machine - - PUBLIC_API_BASE_URL=http://localhost:8000/api - command: sh -c "npm install && JWT_SECRET=${JWT_SECRET} npm run dev -- --host 0.0.0.0 --port 3000" - extra_hosts: - - "host.docker.internal:host-gateway" - depends_on: - - postgres - - postgres: - image: postgres:16-alpine - ports: - - "5432:5432" - environment: - - POSTGRES_USER=csf_user - - POSTGRES_PASSWORD=csf_password - - POSTGRES_DB=csf_core - volumes: - - postgres_data:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U csf_user -d csf_core"] - interval: 10s - timeout: 5s - retries: 5 - -volumes: - postgres_data: diff --git a/docker-compose.local.yml b/docker-compose.local.yml deleted file mode 100644 index bfc3280..0000000 --- a/docker-compose.local.yml +++ /dev/null @@ -1,40 +0,0 @@ -version: '3.8' - -services: - postgres: - image: postgres:16-alpine - container_name: csf-postgres-local - ports: - - "5432:5432" - environment: - - POSTGRES_USER=csf_user - - POSTGRES_PASSWORD=csf_password - - POSTGRES_DB=csf_core - volumes: - - postgres_data_local:/var/lib/postgresql/data - healthcheck: - test: ["CMD-SHELL", "pg_isready -U csf_user -d csf_core"] - interval: 10s - timeout: 5s - retries: 5 - - frontend: - build: - context: ./frontend - dockerfile: Dockerfile.dev - container_name: csf-frontend-local - ports: - - "3000:3000" - env_file: - - .env - volumes: - - ./frontend:/app - - /app/node_modules - environment: - - NODE_ENV=development - - PUBLIC_API_BASE_URL=http://localhost:8000/api - command: sh -c "npm install && npm run dev -- --host 0.0.0.0 --port 3000" - restart: unless-stopped - -volumes: - postgres_data_local: diff --git a/docker-compose.registry.yml b/docker-compose.registry.yml deleted file mode 100644 index 1d86ce3..0000000 --- a/docker-compose.registry.yml +++ /dev/null @@ -1,42 +0,0 @@ -# Docker Compose configuration using GitHub Container Registry images -# This file uses the published Docker images from ghcr.io - -version: '3.8' - -services: - backend: - image: ghcr.io/cs-foundry/csf-core-backend:latest - container_name: csf-backend - ports: - - "8000:8000" - environment: - - DATABASE_URL=sqlite:/data/finance.db - - RUST_LOG=info - - JWT_SECRET=${JWT_SECRET:-changeme} - - FRONTEND_URL=http://frontend:80 - volumes: - - csf_data:/data - restart: unless-stopped - healthcheck: - test: ["CMD", "/app/backend", "--health-check"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - - frontend: - image: ghcr.io/cs-foundry/csf-core-frontend:latest - container_name: csf-frontend - ports: - - "3000:80" - restart: unless-stopped - depends_on: - - backend - -volumes: - csf_data: - driver: local - -networks: - default: - name: csf-network diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100644 index c673e78..0000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -set -e - -echo "πŸš€ Starting FinanceVault..." - -# Ensure environment variables are set -export RUST_LOG=${RUST_LOG:-info} -export DATABASE_URL=${DATABASE_URL:-sqlite:/data/finance.db} -export FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000} - -# Check if database directory exists -mkdir -p /data -echo "πŸ“ Data directory: /data" -echo "πŸ’Ύ Database URL: $DATABASE_URL" -echo "πŸ”§ Rust Log Level: $RUST_LOG" -echo "🌐 Frontend URL: $FRONTEND_URL" -echo "" - -# Start frontend (SvelteKit with adapter-node) in background -echo "🎨 Starting Frontend on port 3000..." -cd /app/frontend - -# Start frontend with logs going to stdout (with prefix) -(PORT=3000 HOST=0.0.0.0 ORIGIN=${ORIGIN:-http://localhost:8000} node build/index.js 2>&1 | sed 's/^/[FRONTEND] /') & -FRONTEND_PID=$! - -echo " Frontend PID: $FRONTEND_PID" -echo "" - -# Wait for frontend to start -echo "⏳ Waiting for frontend to initialize..." -sleep 3 - -if ! kill -0 $FRONTEND_PID 2>/dev/null; then - echo "❌ Frontend failed to start!" - exit 1 -fi - -# Check if frontend is responding -MAX_RETRIES=10 -RETRY=0 -while [ $RETRY -lt $MAX_RETRIES ]; do - if curl -f http://localhost:3000/ 2>/dev/null > /dev/null; then - echo "βœ… Frontend health check passed" - break - fi - RETRY=$((RETRY+1)) - if [ $RETRY -lt $MAX_RETRIES ]; then - echo "⏳ Frontend not ready yet, retrying ($RETRY/$MAX_RETRIES)..." - sleep 2 - else - echo "⚠️ Frontend health check failed after $MAX_RETRIES attempts (will proceed anyway)" - fi -done - -echo "" - -# Start backend (which proxies to frontend) -echo "πŸ“¦ Starting Backend on port 8000 (with frontend proxy)..." -cd /app - -# Start backend in foreground with logging -RUST_LOG=$RUST_LOG DATABASE_URL=$DATABASE_URL FRONTEND_URL=$FRONTEND_URL exec ./backend - diff --git a/docs/.github/CICD.md b/docs/.github/CICD.md deleted file mode 100644 index 9328923..0000000 --- a/docs/.github/CICD.md +++ /dev/null @@ -1,194 +0,0 @@ -# CI/CD Workflow Documentation πŸš€ - -## Überblick - -Das FinanceVault Projekt nutzt einen **automatisierten Release- und Build-Prozess** mit semantic-release und GitHub Actions. - -## Workflow-Ablauf - -### 1. Release Pipeline (`release.yml`) - -**Trigger:** Push auf den `main` Branch - -**Ablauf:** -1. βœ… Commit-Analyzer prΓΌft Commit-Messages (Conventional Commits) -2. πŸ“Š Bestimmt die neue Version (major/minor/patch) -3. πŸ“ Generiert CHANGELOG.md -4. πŸ”„ Aktualisiert Versionen in: - - `package.json` (Root) - - `frontend/package.json` - - `backend/Cargo.toml` -5. 🏷️ Erstellt Git Tag (z.B. `v1.2.3`) -6. πŸ“¦ Erstellt GitHub Release -7. βš™οΈ Committed Γ„nderungen zurΓΌck (`[skip ci]`) - -**Ausgabe:** -- GitHub Release mit Changelog -- Versionierte Dateien im Repository -- Git Tag fΓΌr Docker Build - -### 2. Docker Build Pipeline (`docker-build-push.yml`) - -**Trigger:** -- Git Tag `v*` (wird vom Release-Workflow erstellt) -- Manueller Trigger (`workflow_dispatch`) - -**Ablauf:** -1. πŸ—οΈ Baut AMD64 Image -2. πŸ—οΈ Baut ARM64 Image -3. πŸ”— Erstellt Multi-Arch Manifest -4. πŸ“€ Pushed zu GitHub Container Registry - -**Tags:** -- `v1.2.3` (exakte Version vom Git Tag) -- `v1.2` (Major.Minor) -- `latest` (nur fΓΌr main branch) -- `main-sha123-amd64` / `main-sha123-arm64` (Arch-spezifisch) - -## Commit Message Format - -Wir verwenden [Conventional Commits](https://www.conventionalcommits.org/): - -``` -(): - - - -