mirror of
https://github.com/Portabase/agent.git
synced 2026-09-11 14:00:14 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f6f378d584 | |||
| 66c0b04759 | |||
| c348253015 | |||
| e83e44a39e | |||
| 92d64c0b4b | |||
| abd39e2db1 | |||
| 48a4ef6cc2 | |||
| 358bffd675 | |||
| 25e08a2b94 | |||
| dc563d3cfd | |||
| 92ad1cbfb4 | |||
| 82d5306dd4 | |||
| 52714cda21 | |||
| fa46d1bbc4 | |||
| 5535b4b22f | |||
| 0e86a813b5 | |||
| ecdb4a067d | |||
| 8078d733e4 | |||
| 06c4a05cbe | |||
| 6985260a8e | |||
| 313693f50b | |||
| 2e7ccb7897 | |||
| 11cba862ab | |||
| 7b40ce6d83 | |||
| e6b0653e48 | |||
| a215c95b5e | |||
| 6fb3b8bb37 | |||
| aedb6a0ebc | |||
| 97c770becf | |||
| 73279f5b76 | |||
| 8f7b0523a4 | |||
| 321d9a5ca9 | |||
| a23571bcb2 | |||
| ab22b44c18 | |||
| fcac5bd0da | |||
| 2b8628899d | |||
| 2e11ba2fd4 | |||
| 7d424a78f1 | |||
| 6089e19412 | |||
| 952c70de61 | |||
| 99c42206c1 | |||
| 09b1869833 | |||
| b2f8d56efb | |||
| ddffae0d23 |
@@ -26,76 +26,92 @@ on:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
contents: read
|
||||
|
||||
build:
|
||||
name: Build and push Docker images
|
||||
runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-latest' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [linux/amd64, linux/arm64]
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up QEMU (multi-arch support)
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
- name: Login to Docker
|
||||
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Set tags
|
||||
- name: Set image tag
|
||||
id: set-tags
|
||||
run: |
|
||||
REF_NAME=${GITHUB_REF#refs/tags/}
|
||||
TAGS="${{ inputs.image_name }}:$REF_NAME"
|
||||
if [[ "${{ inputs.add_latest }}" == "true" ]]; then
|
||||
TAGS="$TAGS,${{ inputs.image_name }}:latest"
|
||||
if [ "${{ matrix.platform }}" = "linux/amd64" ]; then
|
||||
IMAGE="${{ inputs.image_name }}:$REF_NAME-amd64"
|
||||
else
|
||||
IMAGE="${{ inputs.image_name }}:$REF_NAME-arm64"
|
||||
fi
|
||||
echo "tags=$TAGS" >> $GITHUB_OUTPUT
|
||||
echo "image=$IMAGE" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build amd64 image
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ inputs.dockerfile }}
|
||||
platforms: linux/amd64
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: true
|
||||
tags: ${{ inputs.image_name }}:amd64
|
||||
tags: ${{ steps.set-tags.outputs.image }}
|
||||
target: ${{ inputs.target }}
|
||||
cache-from: type=registry,ref=${{ inputs.image_name }}:buildcache-amd64
|
||||
cache-to: type=registry,ref=${{ inputs.image_name }}:buildcache-amd64,mode=max
|
||||
|
||||
- name: Build arm64 image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: ${{ inputs.dockerfile }}
|
||||
platforms: linux/arm64
|
||||
push: true
|
||||
tags: ${{ inputs.image_name }}:arm64
|
||||
target: ${{ inputs.target }}
|
||||
cache-from: type=registry,ref=${{ inputs.image_name }}:buildcache-arm64
|
||||
cache-to: type=registry,ref=${{ inputs.image_name }}:buildcache-arm64,mode=max
|
||||
|
||||
- name: Create and push multi-arch manifest
|
||||
- name: Prepare artifact name
|
||||
id: artifact
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "safe_platform=${platform//\//-}" >> $GITHUB_OUTPUT
|
||||
echo "${{ steps.set-tags.outputs.image }}" > image.txt
|
||||
|
||||
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
|
||||
with:
|
||||
name: image-${{ steps.artifact.outputs.safe_platform }}
|
||||
path: image.txt
|
||||
if-no-files-found: warn
|
||||
compression-level: 6
|
||||
overwrite: false
|
||||
include-hidden-files: false
|
||||
|
||||
create-manifest:
|
||||
name: Create multi-arch Docker manifest
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
|
||||
with:
|
||||
name: image-linux-amd64
|
||||
path: /tmp/digests/amd64
|
||||
|
||||
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
|
||||
with:
|
||||
name: image-linux-arm64
|
||||
path: /tmp/digests/arm64
|
||||
|
||||
- name: Login to Docker
|
||||
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Create and push manifest list
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
DOCKER_IMAGES="$(cat amd64/image.txt) $(cat arm64/image.txt)"
|
||||
REF_NAME=${GITHUB_REF#refs/tags/}
|
||||
docker manifest create ${{ inputs.image_name }}:$REF_NAME \
|
||||
--amend ${{ inputs.image_name }}:amd64 \
|
||||
--amend ${{ inputs.image_name }}:arm64
|
||||
docker manifest push ${{ inputs.image_name }}:$REF_NAME
|
||||
if [[ "${{ inputs.add_latest }}" == "true" ]]; then
|
||||
docker manifest create ${{ inputs.image_name }}:latest \
|
||||
--amend ${{ inputs.image_name }}:amd64 \
|
||||
--amend ${{ inputs.image_name }}:arm64
|
||||
docker manifest push ${{ inputs.image_name }}:latest
|
||||
fi
|
||||
MANIFEST_IMAGE="${{ inputs.image_name }}:$REF_NAME"
|
||||
|
||||
docker buildx imagetools create $DOCKER_IMAGES -t $MANIFEST_IMAGE
|
||||
docker buildx imagetools inspect $MANIFEST_IMAGE
|
||||
|
||||
if [ "${{ inputs.add_latest }}" = "true" ]; then
|
||||
docker buildx imagetools create $DOCKER_IMAGES -t ${{ inputs.image_name }}:latest
|
||||
docker buildx imagetools inspect ${{ inputs.image_name }}:latest
|
||||
fi
|
||||
+2
-2
@@ -22,5 +22,5 @@ keywords:
|
||||
- self-hosted
|
||||
- portabase
|
||||
license: Apache-2.0
|
||||
version: 1.0.3-rc.8
|
||||
date-released: "2026-01-28"
|
||||
version: 1.0.5-rc.1
|
||||
date-released: "2026-02-01"
|
||||
Generated
+87
-47
@@ -51,6 +51,28 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03918c3dbd7701a85c6b9887732e2921175f26c350b4563841d0958c21d57e6d"
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.89"
|
||||
@@ -76,9 +98,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.15.3"
|
||||
version = "1.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e84ce723ab67259cfeb9877c6a639ee9eb7a27b28123abd71db7f0d5d0cc9d86"
|
||||
checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"zeroize",
|
||||
@@ -86,9 +108,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.36.0"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a442ece363113bd4bd4c8b18977a7798dd4d3c3383f34fb61936960e8f4ad8"
|
||||
checksum = "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cmake",
|
||||
@@ -172,9 +194,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.53"
|
||||
version = "1.2.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932"
|
||||
checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -558,9 +580,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.8"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
@@ -927,7 +949,7 @@ dependencies = [
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
@@ -937,9 +959,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.64"
|
||||
version = "0.1.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
@@ -1321,9 +1343,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "moka"
|
||||
version = "0.12.12"
|
||||
version = "0.12.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a"
|
||||
checksum = "b4ac832c50ced444ef6be0767a008b02c106a909ba79d1d830501e94b96f6b7e"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-epoch",
|
||||
@@ -1387,7 +1409,7 @@ dependencies = [
|
||||
"serde_with",
|
||||
"sha1",
|
||||
"sha2",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"stringprep",
|
||||
"strsim",
|
||||
"take_mut",
|
||||
@@ -1433,9 +1455,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
@@ -1595,11 +1617,13 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "portabase-agent"
|
||||
version = "1.0.3-rc.7"
|
||||
version = "1.0.4"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"base64",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"cron",
|
||||
"dotenvy",
|
||||
@@ -1610,6 +1634,7 @@ dependencies = [
|
||||
"mongodb",
|
||||
"once_cell",
|
||||
"openssl",
|
||||
"rand",
|
||||
"redis",
|
||||
"reqwest",
|
||||
"serde",
|
||||
@@ -1620,10 +1645,10 @@ dependencies = [
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-postgres",
|
||||
"tokio-util",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-log",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
@@ -1708,7 +1733,7 @@ dependencies = [
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@@ -1746,16 +1771,16 @@ dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"tracing",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.43"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -1803,9 +1828,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfe20977fe93830c0e9817a16fbf1ed1cfd8d4bba366087a1841d2c6033c251"
|
||||
checksum = "e969d1d702793536d5fda739a82b88ad7cbe7d04f8386ee8cd16ad3eff4854a5"
|
||||
dependencies = [
|
||||
"arcstr",
|
||||
"bytes",
|
||||
@@ -1818,7 +1843,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"ryu",
|
||||
"sha1_smol",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"url",
|
||||
@@ -1894,12 +1919,14 @@ dependencies = [
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
@@ -2249,9 +2276,9 @@ checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
@@ -2277,9 +2304,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
|
||||
checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
@@ -2459,9 +2486,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.45"
|
||||
version = "0.3.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
|
||||
checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
@@ -2476,15 +2503,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.25"
|
||||
version = "0.2.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd"
|
||||
checksum = "78cc610bac2dcee56805c99642447d4c5dbde4d01f752ffea0199aee1f601dc4"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
@@ -2535,7 +2562,7 @@ dependencies = [
|
||||
"mio",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
@@ -2571,7 +2598,7 @@ dependencies = [
|
||||
"postgres-protocol",
|
||||
"postgres-types",
|
||||
"rand",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"whoami",
|
||||
@@ -2863,9 +2890,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.19.0"
|
||||
version = "1.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
||||
checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"js-sys",
|
||||
@@ -3002,6 +3029,19 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.85"
|
||||
@@ -3042,9 +3082,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "2.0.2"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace4d5c7b5ab3d99629156d4e0997edbe98a4beb6d5ba99e2cae830207a81983"
|
||||
checksum = "8fae98cf96deed1b7572272dfc777713c249ae40aa1cf8862e091e8b745f5361"
|
||||
dependencies = [
|
||||
"libredox",
|
||||
"wasite",
|
||||
@@ -3511,18 +3551,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.33"
|
||||
version = "0.8.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd"
|
||||
checksum = "7456cf00f0685ad319c5b1693f291a650eaf345e941d082fc4e03df8a03996ac"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.33"
|
||||
version = "0.8.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
|
||||
checksum = "1328722bbf2115db7e19d69ebcc15e795719e2d66b60827c6a69a117365e37a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3591,6 +3631,6 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.16"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65"
|
||||
checksum = "02aae0f83f69aafc94776e879363e9771d7ecbffe2c7fbb6c14c5e00dfe88439"
|
||||
|
||||
+6
-3
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "portabase-agent"
|
||||
version = "1.0.3-rc.8"
|
||||
version = "1.0.5-rc.1"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
@@ -17,7 +17,7 @@ base64 = "0.22.1"
|
||||
thiserror = "2.0.17"
|
||||
log = "0.4.29"
|
||||
toml = "0.9.10"
|
||||
reqwest = { version = "0.13.1", features = ["json", "blocking", "multipart"] }
|
||||
reqwest = { version = "0.13.1", features = ["json", "blocking", "multipart", "stream"] }
|
||||
anyhow = "1.0.100"
|
||||
tokio = { version = "1.49.0", features = ["rt", "rt-multi-thread", "macros", "fs"] }
|
||||
async-trait = "0.1.89"
|
||||
@@ -28,10 +28,13 @@ flate2 = "1.1.5"
|
||||
tar = "0.4.44"
|
||||
tokio-postgres = "0.7.15"
|
||||
futures = "0.3.31"
|
||||
tracing-log = "0.2.0"
|
||||
tracing-appender = "0.2.4"
|
||||
time = { version = "0.3.44", features = ["macros"] }
|
||||
mongodb = "3.5.0"
|
||||
rand = "0.9.2"
|
||||
tokio-util = "0.7.18"
|
||||
bytes = "1.11.0"
|
||||
async-stream = "0.3.6"
|
||||
|
||||
[[bin]]
|
||||
name = "app"
|
||||
|
||||
@@ -15,6 +15,10 @@ seed-mysql:
|
||||
@echo "Seeding MySQL..."
|
||||
mysql -h 127.0.0.1 -P "$$MYSQL_PORT" -u "$$MYSQL_USER" -p"$$MYSQL_PASSWORD" "$$MYSQL_DB" < ./scripts/mysql/seed-mysql.sql
|
||||
|
||||
seed-mysql-1gb:
|
||||
@echo "Seeding MySQL..."
|
||||
mysql -h 127.0.0.1 -P "$$MYSQL_PORT" -u "$$MYSQL_USER" -p"$$MYSQL_PASSWORD" "$$MYSQL_DB" < ./scripts/mysql/seed-1gb.sql
|
||||
|
||||
|
||||
seed-postgres:
|
||||
@echo "Seeding Postgres..."
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+48
-5
@@ -1,10 +1,11 @@
|
||||
services:
|
||||
rust-app:
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: docker/Dockerfile
|
||||
# target: prod
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: docker/Dockerfile
|
||||
# target: prod
|
||||
image: portabase/agent:latest
|
||||
# platform: linux/arm64
|
||||
container_name: rust-prod
|
||||
volumes:
|
||||
- ./databases.json:/config/config.json
|
||||
@@ -13,7 +14,7 @@ services:
|
||||
LOG: info
|
||||
TZ: "Europe/Paris"
|
||||
# DATABASES_CONFIG_FILE: "config.toml"
|
||||
EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiY2VlZmNmNDQtOGE0YS00NjZlLTkwNDEtN2QzNDMzZjRjOTJkIiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXG5NSUlCQ2dLQ0FRRUFuYUVKdnVBSExlNGF5d0RmNGplelVobm45VXRkdksyZ3pEMEg2cERJYXczYkJKRkpwVnVDXG5uVFV3MXA3Q2RnOXBzdjZhRnpyOXZPd0J2MjMzckxpdVpCT2lCb2p2Q0QrSlZid3hyTzBRRW5hN2dmaHV1ZGYwXG5VVlJOMkxmK1g1aTkvZzJTNm5xcExoTm1DaGFJNk8ybktYZUNlRmtubEErRUJrNnFoV1FCVGozb05TYTFTOFY1XG40UFRTT2I4NUo3a2k5YllEbXRiNWxrU3dCNXdXOTdtQjg0ZzI2WHAvU3FFcmhKc0NGK3YrN09vTWYzTzJqTTNoXG5XMUQ0MzBPRitWaklwUGdoV09rZy96NXZQUWFHRzhqQ0h4VDlJR0Q0bjhyS05LQ3FTOGNyN2diTGU0cWpNdmhvXG5BQVVvaHpHR2FRNkhlWlJ4S0UvM3J1a2JldnY5dnJ2TTNRSURBUUFCXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXG4ifQ"
|
||||
EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiOGZmMDE4NTQtYjJhMS00ZTE0LTkwMjctZTJiOWIxZjQ1YzdlIiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXG5NSUlCQ2dLQ0FRRUE5TWV4M2pmdnVLdFB5YU1ERnh2Ulp2dmd3YkRJQ2JzQi81Wll5NDNSVVRBaXZRYjJiSDdYXG5qRHBQd1lJeCs4UFBrbHlRbDVMQzV1UWZEaCs4SVd4OG1LZ3FvMXpWMkdiZXdGbEdEWFYxVEdyU1ZEU25aSWR4XG52bWdYc29EeXhVMlJvWUFUMS9YMWxuc2YxenZKdkFMTkhXdEhRdk42SjVDZTFSMmFsendVRGFEVXlJNzRmSldQXG5tNTh0SDMrYklXL0VVTXdjaWNxM0oySWw3Vm9KNkZNUHJQL1ZSOWEvdFF1SU1qa200MXpFY2NscExPa2luRkxuXG54NmVUWkFSZUpya2UrbnRvZ2t4TGEyRWV5a1lUNzB4V3hKNWp5ZExBVnRvNkkyQlVLVVJoTkowTUFaU29NYUtvXG5iMGJRcnY1UzExZWllMnMrT2I3aTYzSFpkVUx0UmV1MVJ3SURBUUFCXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXG4ifQ"
|
||||
extra_hosts:
|
||||
- "localhost:host-gateway"
|
||||
networks:
|
||||
@@ -21,6 +22,48 @@ services:
|
||||
|
||||
|
||||
|
||||
db-mongodb-auth:
|
||||
container_name: db-mongodb-auth
|
||||
image: mongo:latest
|
||||
ports:
|
||||
- "27082:27017"
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
MONGO_INITDB_ROOT_PASSWORD: rootpassword
|
||||
MONGO_INITDB_DATABASE: testdbauth
|
||||
command: mongod --auth
|
||||
networks:
|
||||
- portabase
|
||||
volumes:
|
||||
- mongodb-data-auth:/data/db
|
||||
healthcheck:
|
||||
test: [ "CMD", "mongo", "--eval", "db.adminCommand('ping')" ]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
db-mongodb:
|
||||
container_name: db-mongodb
|
||||
image: mongo:latest
|
||||
ports:
|
||||
- "27083:27017"
|
||||
volumes:
|
||||
- mongodb-data:/data/db
|
||||
healthcheck:
|
||||
test: [ "CMD", "mongosh", "--eval", "db.adminCommand('ping')" ]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
environment:
|
||||
MONGO_INITDB_DATABASE: testdb
|
||||
networks:
|
||||
- portabase
|
||||
|
||||
volumes:
|
||||
mongodb-data:
|
||||
mongodb-data-auth:
|
||||
|
||||
|
||||
networks:
|
||||
portabase:
|
||||
name: portabase_network
|
||||
|
||||
+68
-69
@@ -4,7 +4,6 @@ services:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile
|
||||
target: dev
|
||||
platform: linux/arm64
|
||||
container_name: rust-dev
|
||||
volumes:
|
||||
- .:/app
|
||||
@@ -12,12 +11,12 @@ services:
|
||||
# - ./databases.toml:/config/config.toml
|
||||
- cargo-registry:/usr/local/cargo/registry
|
||||
- cargo-git:/usr/local/cargo/git
|
||||
- cargo-target:/app/target
|
||||
# - cargo-target:/app/target
|
||||
environment:
|
||||
APP_ENV: development
|
||||
LOG: debug
|
||||
TZ: "Europe/Paris"
|
||||
EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiNmExMzc0M2ItYjMwZS00Zjg4LWJjY2EtMmMwZjE2NWVjYjQxIiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXG5NSUlCQ2dLQ0FRRUE5TWV4M2pmdnVLdFB5YU1ERnh2Ulp2dmd3YkRJQ2JzQi81Wll5NDNSVVRBaXZRYjJiSDdYXG5qRHBQd1lJeCs4UFBrbHlRbDVMQzV1UWZEaCs4SVd4OG1LZ3FvMXpWMkdiZXdGbEdEWFYxVEdyU1ZEU25aSWR4XG52bWdYc29EeXhVMlJvWUFUMS9YMWxuc2YxenZKdkFMTkhXdEhRdk42SjVDZTFSMmFsendVRGFEVXlJNzRmSldQXG5tNTh0SDMrYklXL0VVTXdjaWNxM0oySWw3Vm9KNkZNUHJQL1ZSOWEvdFF1SU1qa200MXpFY2NscExPa2luRkxuXG54NmVUWkFSZUpya2UrbnRvZ2t4TGEyRWV5a1lUNzB4V3hKNWp5ZExBVnRvNkkyQlVLVVJoTkowTUFaU29NYUtvXG5iMGJRcnY1UzExZWllMnMrT2I3aTYzSFpkVUx0UmV1MVJ3SURBUUFCXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXG4ifQ"
|
||||
EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiYTMxNWFhZmUtNDcyNi00OWM0LThhMmEtMGM2ZWQ0N2E1NjVkIiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXG5NSUlCQ2dLQ0FRRUE5TWV4M2pmdnVLdFB5YU1ERnh2Ulp2dmd3YkRJQ2JzQi81Wll5NDNSVVRBaXZRYjJiSDdYXG5qRHBQd1lJeCs4UFBrbHlRbDVMQzV1UWZEaCs4SVd4OG1LZ3FvMXpWMkdiZXdGbEdEWFYxVEdyU1ZEU25aSWR4XG52bWdYc29EeXhVMlJvWUFUMS9YMWxuc2YxenZKdkFMTkhXdEhRdk42SjVDZTFSMmFsendVRGFEVXlJNzRmSldQXG5tNTh0SDMrYklXL0VVTXdjaWNxM0oySWw3Vm9KNkZNUHJQL1ZSOWEvdFF1SU1qa200MXpFY2NscExPa2luRkxuXG54NmVUWkFSZUpya2UrbnRvZ2t4TGEyRWV5a1lUNzB4V3hKNWp5ZExBVnRvNkkyQlVLVVJoTkowTUFaU29NYUtvXG5iMGJRcnY1UzExZWllMnMrT2I3aTYzSFpkVUx0UmV1MVJ3SURBUUFCXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXG4ifQ"
|
||||
#POOLING: 1
|
||||
#DATABASES_CONFIG_FILE: "config.toml"
|
||||
extra_hosts:
|
||||
@@ -25,83 +24,83 @@ services:
|
||||
networks:
|
||||
- portabase
|
||||
|
||||
# db-postgres:
|
||||
# container_name: db-postgres
|
||||
# image: postgres:17-alpine
|
||||
# ports:
|
||||
# - "5436:5432"
|
||||
# volumes:
|
||||
# - postgres-data:/var/lib/postgresql/data
|
||||
# environment:
|
||||
# - POSTGRES_DB=devdb
|
||||
# - POSTGRES_USER=devuser
|
||||
# - POSTGRES_PASSWORD=changeme
|
||||
# networks:
|
||||
# - portabase
|
||||
db-postgres:
|
||||
container_name: db-postgres
|
||||
image: postgres:17-alpine
|
||||
ports:
|
||||
- "5436:5432"
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
- POSTGRES_DB=devdb
|
||||
- POSTGRES_USER=devuser
|
||||
- POSTGRES_PASSWORD=changeme
|
||||
networks:
|
||||
- portabase
|
||||
|
||||
db-mariadb:
|
||||
container_name: db-mariadb
|
||||
image: mariadb:latest
|
||||
ports:
|
||||
- "3311:3306"
|
||||
environment:
|
||||
- MYSQL_DATABASE=mariadb
|
||||
- MYSQL_USER=mariadb
|
||||
- MYSQL_PASSWORD=changeme
|
||||
- MYSQL_RANDOM_ROOT_PASSWORD=yes
|
||||
volumes:
|
||||
- mariadb-data:/var/lib/mysql
|
||||
networks:
|
||||
- portabase
|
||||
|
||||
#
|
||||
# db-mariadb:
|
||||
# container_name: db-mariadb
|
||||
# image: mariadb:latest
|
||||
# db-mongodb-auth:
|
||||
# container_name: db-mongodb-auth
|
||||
# image: mongo:latest
|
||||
# ports:
|
||||
# - "3311:3306"
|
||||
# - "27082:27017"
|
||||
# environment:
|
||||
# - MYSQL_DATABASE=mariadb
|
||||
# - MYSQL_USER=mariadb
|
||||
# - MYSQL_PASSWORD=changeme
|
||||
# - MYSQL_RANDOM_ROOT_PASSWORD=yes
|
||||
# volumes:
|
||||
# - mariadb-data:/var/lib/mysql
|
||||
# MONGO_INITDB_ROOT_USERNAME: root
|
||||
# MONGO_INITDB_ROOT_PASSWORD: rootpassword
|
||||
# MONGO_INITDB_DATABASE: testdbauth
|
||||
# command: mongod --auth
|
||||
# networks:
|
||||
# - portabase
|
||||
# volumes:
|
||||
# - mongodb-data-auth:/data/db
|
||||
# healthcheck:
|
||||
# test: [ "CMD", "mongo", "--eval", "db.adminCommand('ping')" ]
|
||||
# interval: 5s
|
||||
# timeout: 5s
|
||||
# retries: 10
|
||||
#
|
||||
# db-mongodb:
|
||||
# container_name: db-mongodb
|
||||
# image: mongo:latest
|
||||
# ports:
|
||||
# - "27083:27017"
|
||||
# volumes:
|
||||
# - mongodb-data:/data/db
|
||||
# healthcheck:
|
||||
# test: [ "CMD", "mongosh", "--eval", "db.adminCommand('ping')" ]
|
||||
# interval: 5s
|
||||
# timeout: 5s
|
||||
# retries: 10
|
||||
# environment:
|
||||
# MONGO_INITDB_DATABASE: testdb
|
||||
# networks:
|
||||
# - portabase
|
||||
|
||||
|
||||
db-mongodb-auth:
|
||||
container_name: db-mongodb-auth
|
||||
image: mongo:latest
|
||||
ports:
|
||||
- "27082:27017"
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: root
|
||||
MONGO_INITDB_ROOT_PASSWORD: rootpassword
|
||||
MONGO_INITDB_DATABASE: testdbauth
|
||||
command: mongod --auth
|
||||
networks:
|
||||
- portabase
|
||||
volumes:
|
||||
- mongodb-data-auth:/data/db
|
||||
healthcheck:
|
||||
test: [ "CMD", "mongo", "--eval", "db.adminCommand('ping')" ]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
db-mongodb:
|
||||
container_name: db-mongodb
|
||||
image: mongo:latest
|
||||
ports:
|
||||
- "27083:27017"
|
||||
volumes:
|
||||
- mongodb-data:/data/db
|
||||
healthcheck:
|
||||
test: [ "CMD", "mongosh", "--eval", "db.adminCommand('ping')" ]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
environment:
|
||||
MONGO_INITDB_DATABASE: testdb
|
||||
networks:
|
||||
- portabase
|
||||
|
||||
volumes:
|
||||
cargo-registry:
|
||||
cargo-git:
|
||||
cargo-target:
|
||||
# cargo-target:
|
||||
|
||||
|
||||
# postgres-data:
|
||||
# mariadb-data:
|
||||
mongodb-data:
|
||||
mongodb-data-auth:
|
||||
postgres-data:
|
||||
mariadb-data:
|
||||
# mongodb-data:
|
||||
# mongodb-data-auth:
|
||||
|
||||
networks:
|
||||
portabase:
|
||||
|
||||
+33
-37
@@ -1,9 +1,7 @@
|
||||
# =========================
|
||||
# Base Rust image
|
||||
# Base image (shared)
|
||||
# =========================
|
||||
FROM rust:1.92 AS base
|
||||
|
||||
ARG TARGETARCH
|
||||
FROM rust:1.92.0 AS base
|
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
pkg-config \
|
||||
@@ -17,36 +15,44 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
zlib1g \
|
||||
curl \
|
||||
mariadb-client \
|
||||
wget \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# =========================
|
||||
# PostgreSQL client binaries (only target arch)
|
||||
# =========================
|
||||
RUN for v in 12 13 14 15 16 17 18; do mkdir -p /usr/lib/postgresql/$v/bin; done
|
||||
COPY assets/tools/$TARGETARCH/postgresql/ /tmp/pg/
|
||||
RUN for v in 12 13 14 15 16 17 18; do \
|
||||
cp -r /tmp/pg/postgresql-$v/bin/* /usr/lib/postgresql/$v/bin/; \
|
||||
done && rm -rf /tmp/pg && chmod +x /usr/lib/postgresql/*/bin/*
|
||||
ARG TARGETARCH
|
||||
|
||||
# =========================
|
||||
# MongoDB client binaries (only target arch)
|
||||
# PostgreSQL client binaries (versions 12-18)
|
||||
# =========================
|
||||
|
||||
RUN for v in 12 13 14 15 16 17 18; do \
|
||||
mkdir -p /usr/lib/postgresql/$v/bin; \
|
||||
done
|
||||
|
||||
COPY assets/tools/amd64/postgresql/ /tmp/pg-x64/
|
||||
COPY assets/tools/arm64/postgresql/ /tmp/pg-arm/
|
||||
|
||||
RUN if [ "$TARGETARCH" = "amd64" ]; then \
|
||||
wget -q https://fastdl.mongodb.org/tools/db/mongodb-database-tools-debian12-x86_64-100.10.0.deb -O /tmp/mongodb-tools.deb; \
|
||||
for v in 12 13 14 15 16 17 18; do \
|
||||
cp -r /tmp/pg-x64/postgresql-$v/bin/* /usr/lib/postgresql/$v/bin/; \
|
||||
done; \
|
||||
elif [ "$TARGETARCH" = "arm64" ]; then \
|
||||
wget -q https://fastdl.mongodb.org/tools/db/mongodb-database-tools-ubuntu2204-arm64-100.10.0.deb -O /tmp/mongodb-tools.deb; \
|
||||
fi && dpkg -i /tmp/mongodb-tools.deb || apt-get install -f -y --no-install-recommends && \
|
||||
rm -f /tmp/mongodb-tools.deb && \
|
||||
mkdir -p /usr/local/mongodb/bin && \
|
||||
ln -sf /usr/bin/mongodump /usr/local/mongodb/bin/mongodump || true && \
|
||||
ln -sf /usr/bin/mongorestore /usr/local/mongodb/bin/mongorestore || true
|
||||
for v in 12 13 14 15 16 17 18; do \
|
||||
cp -r /tmp/pg-arm/postgresql-$v/bin/* /usr/lib/postgresql/$v/bin/; \
|
||||
done; \
|
||||
fi && \
|
||||
rm -rf /tmp/pg-x64 /tmp/pg-arm && \
|
||||
chmod +x /usr/lib/postgresql/*/bin/*
|
||||
|
||||
# =========================
|
||||
# MongoDB client binaries
|
||||
# =========================
|
||||
COPY assets/tools/${TARGETARCH}/mongodb/ /usr/local/mongodb/
|
||||
RUN chmod +x /usr/local/mongodb/bin/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# =========================
|
||||
# Development stage
|
||||
# Development image
|
||||
# =========================
|
||||
FROM base AS dev
|
||||
|
||||
@@ -57,26 +63,15 @@ RUN mkdir src && echo "fn main() {}" > src/main.rs
|
||||
RUN cargo build
|
||||
RUN rm -rf src
|
||||
|
||||
COPY . .
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
CMD ["/entrypoint.sh"]
|
||||
|
||||
# =========================
|
||||
# Builder stage for production
|
||||
# Builder (production)
|
||||
# =========================
|
||||
FROM base AS builder
|
||||
WORKDIR /app
|
||||
|
||||
RUN cargo install cargo-chef
|
||||
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
RUN mkdir src && echo "fn main() {}" > src/main.rs
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
RUN cargo chef cook --recipe-path recipe.json --release
|
||||
RUN rm -rf src
|
||||
|
||||
COPY . .
|
||||
RUN cargo build --release
|
||||
@@ -84,7 +79,7 @@ RUN cargo build --release
|
||||
RUN echo "APP_VERSION=$(cargo pkgid | awk -F# '{print $2}')" > /app/version.env
|
||||
|
||||
# =========================
|
||||
# Production runtime
|
||||
# Runtime (production)
|
||||
# =========================
|
||||
FROM ubuntu:24.04 AS prod
|
||||
|
||||
@@ -99,16 +94,17 @@ RUN apt-get update && apt-get install -y \
|
||||
mariadb-client \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/target/release/app /usr/local/bin/app
|
||||
COPY --from=builder /app/version.env /app/version.env
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
COPY --from=base /usr/lib/postgresql/ /usr/lib/postgresql/
|
||||
COPY --from=base /usr/local/mongodb/bin /usr/local/mongodb/bin
|
||||
COPY --from=base /usr/local/mongodb/bin/ /usr/local/mongodb/bin/
|
||||
|
||||
|
||||
ENV APP_ENV=production
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
CREATE DATABASE IF NOT EXISTS mariadb;
|
||||
USE mariadb;
|
||||
|
||||
DROP TABLE IF EXISTS users;
|
||||
DROP TABLE IF EXISTS products;
|
||||
|
||||
CREATE TABLE users (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
email VARCHAR(100) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE products (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
description MEDIUMTEXT,
|
||||
price DECIMAL(10,2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
|
||||
DELIMITER $$
|
||||
|
||||
DROP PROCEDURE IF EXISTS seed_data$$
|
||||
CREATE PROCEDURE seed_data()
|
||||
BEGIN
|
||||
DECLARE i BIGINT DEFAULT 1;
|
||||
DECLARE j BIGINT;
|
||||
DECLARE large_text TEXT;
|
||||
|
||||
SET large_text = REPEAT('Lorem ipsum dolor sit amet, consectetur adipiscing elit. ', 300);
|
||||
|
||||
WHILE i <= 200000 DO
|
||||
INSERT INTO users (username, email, password)
|
||||
VALUES (CONCAT('user', i), CONCAT('user', i, '@example.com'), 'changeme');
|
||||
SET i = i + 1;
|
||||
END WHILE;
|
||||
|
||||
SET i = 1;
|
||||
WHILE i <= 200000 DO
|
||||
INSERT INTO products (name, description, price)
|
||||
VALUES (CONCAT('Product ', i), large_text, ROUND(RAND()*1000,2));
|
||||
SET i = i + 1;
|
||||
END WHILE;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
CALL seed_data();
|
||||
|
||||
DROP PROCEDURE IF EXISTS seed_data;
|
||||
+67
-90
@@ -4,21 +4,16 @@ use crate::core::context::Context;
|
||||
use crate::domain::factory::DatabaseFactory;
|
||||
use crate::services::config::{DatabaseConfig, DatabasesConfig, DbType};
|
||||
use crate::utils::common::BackupMethod;
|
||||
use crate::utils::file::full_extension;
|
||||
use crate::utils::file::{encrypt_file_stream, full_extension};
|
||||
use anyhow::Result;
|
||||
use hex;
|
||||
use openssl::encrypt::Encrypter;
|
||||
use openssl::hash::MessageDigest;
|
||||
use openssl::pkey::PKey;
|
||||
use openssl::rand::rand_bytes;
|
||||
use openssl::rsa::Padding;
|
||||
use openssl::symm::{Cipher, Crypter, Mode};
|
||||
use reqwest::multipart::{Form, Part};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use rand::RngCore;
|
||||
use tempfile::TempDir;
|
||||
use tokio::fs;
|
||||
use tracing::{error, info};
|
||||
use reqwest::Body;
|
||||
use futures::StreamExt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BackupResult {
|
||||
@@ -119,100 +114,82 @@ impl BackupService {
|
||||
|
||||
pub async fn send_result(&self, result: BackupResult, method: BackupMethod) {
|
||||
if result.code.as_deref() == Some("backup_already_in_progress") {
|
||||
info!(
|
||||
"[BackupService] Skipping send for DB {}: backup already in progress",
|
||||
result.generated_id
|
||||
);
|
||||
info!("Skipping send: backup already in progress");
|
||||
return;
|
||||
}
|
||||
|
||||
info!(
|
||||
"[BackupService] DB: {} Type: {} Status: {} File: {:?}",
|
||||
result.generated_id,
|
||||
result.db_type.as_str(),
|
||||
result.status,
|
||||
result.backup_file
|
||||
let Some(file_path) = result.backup_file else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut aes_key = [0u8; 32];
|
||||
rand::rng().fill_bytes(&mut aes_key);
|
||||
|
||||
let mut iv = [0u8; 16];
|
||||
rand::rng().fill_bytes(&mut iv);
|
||||
|
||||
let public_key_pem = self.ctx.edge_key.public_key.as_bytes().to_vec();
|
||||
|
||||
|
||||
let (encrypted_stream, encrypted_key_hex) =
|
||||
match encrypt_file_stream(
|
||||
file_path.clone(),
|
||||
aes_key,
|
||||
iv,
|
||||
public_key_pem,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Encryption failed: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let file_size = std::fs::metadata(&file_path)
|
||||
.map(|m| m.len())
|
||||
.unwrap_or(0);
|
||||
|
||||
let body = Body::wrap_stream(
|
||||
encrypted_stream.map(|r| r.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)))
|
||||
);
|
||||
|
||||
let url = format!(
|
||||
"{}/api/agent/{}/backup",
|
||||
// "{}/services/v1/upload/{}",
|
||||
self.ctx.edge_key.server_url,
|
||||
self.ctx.edge_key.agent_id
|
||||
);
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
let url = format!(
|
||||
"{}/api/agent/{}/backup",
|
||||
self.ctx.edge_key.server_url, self.ctx.edge_key.agent_id
|
||||
);
|
||||
|
||||
let mut form = Form::new()
|
||||
.text("generatedId", result.generated_id.clone())
|
||||
.text("status", result.status.clone())
|
||||
.text("method", method.to_string());
|
||||
|
||||
if let Some(file_path) = result.backup_file {
|
||||
match fs::read(&file_path).await {
|
||||
Ok(raw_data) => {
|
||||
// AES key + IV
|
||||
let mut aes_key = [0u8; 32];
|
||||
rand_bytes(&mut aes_key).unwrap();
|
||||
info!("file Size to {}", file_size);
|
||||
|
||||
let mut iv = [0u8; 16];
|
||||
rand_bytes(&mut iv).unwrap();
|
||||
let resp = client
|
||||
.post(&url)
|
||||
.header("X-Generated-Id", &result.generated_id)
|
||||
.header("X-Status", &result.status)
|
||||
.header("X-Method", method.to_string())
|
||||
.header("X-AES-Key", encrypted_key_hex)
|
||||
.header("X-IV", hex::encode(iv))
|
||||
.header("X-Extension", full_extension(&file_path))
|
||||
.header("Transfer-Encoding", "chunked")
|
||||
.header("X-File-Size", file_size)
|
||||
.body(body)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
// AES CBC PKCS7 encryption
|
||||
let cipher = Cipher::aes_256_cbc();
|
||||
let mut encrypter =
|
||||
Crypter::new(cipher, Mode::Encrypt, &aes_key, Some(&iv)).unwrap();
|
||||
encrypter.pad(true);
|
||||
let mut encrypted = vec![0u8; raw_data.len() + cipher.block_size()];
|
||||
let count = encrypter.update(&raw_data, &mut encrypted).unwrap();
|
||||
let rest = encrypter.finalize(&mut encrypted[count..]).unwrap();
|
||||
encrypted.truncate(count + rest);
|
||||
|
||||
// Encrypt AES key with RSA public key
|
||||
let pub_key_pem = self.ctx.edge_key.public_key.as_bytes();
|
||||
let pkey = PKey::public_key_from_pem(pub_key_pem).unwrap();
|
||||
|
||||
let mut encrypter = Encrypter::new(&pkey).unwrap();
|
||||
// Set OAEP padding (default OAEP uses SHA1, so override)
|
||||
encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
|
||||
// Set OAEP hash to SHA‑256
|
||||
encrypter.set_rsa_oaep_md(MessageDigest::sha256()).unwrap();
|
||||
encrypter.set_rsa_mgf1_md(MessageDigest::sha256()).unwrap();
|
||||
|
||||
let mut encrypted_key = vec![0u8; encrypter.encrypt_len(&aes_key).unwrap()];
|
||||
let encrypted_len = encrypter.encrypt(&aes_key, &mut encrypted_key).unwrap();
|
||||
encrypted_key.truncate(encrypted_len);
|
||||
|
||||
let extension = full_extension(&file_path);
|
||||
|
||||
// Attach file and AES info to multipart form
|
||||
form = form
|
||||
.part(
|
||||
"file",
|
||||
Part::bytes(encrypted)
|
||||
.file_name(format!("{}.enc", result.generated_id)),
|
||||
)
|
||||
.text("aes_key", hex::encode(encrypted_key))
|
||||
.text("iv", hex::encode(iv))
|
||||
.text("extension", extension);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to read backup file: {}", e);
|
||||
}
|
||||
match resp {
|
||||
Ok(r) if r.status().is_success() => {
|
||||
info!("Backup uploaded successfully");
|
||||
}
|
||||
} else {
|
||||
form = form.text("file", "");
|
||||
}
|
||||
|
||||
match client.post(&url).multipart(form).send().await {
|
||||
Ok(resp) => {
|
||||
let status = resp.status();
|
||||
if status.is_success() {
|
||||
info!("Backup result sent successfully");
|
||||
} else {
|
||||
let text = resp.text().await.unwrap_or_default(); // consumes resp
|
||||
error!("Backup result failed, status: {}, body: {}", status, text);
|
||||
}
|
||||
Ok(r) => {
|
||||
error!("Upload failed: {}", r.status());
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to send backup result: {}", e);
|
||||
error!("Upload error: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+71
-9
@@ -1,15 +1,77 @@
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use anyhow::Result;
|
||||
use tokio::fs::File;
|
||||
use tokio::io::{AsyncReadExt, BufReader};
|
||||
use futures::{Stream};
|
||||
use bytes::Bytes;
|
||||
use openssl::symm::{Cipher, Crypter, Mode};
|
||||
use openssl::pkey::PKey;
|
||||
use openssl::encrypt::Encrypter;
|
||||
use openssl::rsa::Padding;
|
||||
use openssl::hash::MessageDigest;
|
||||
use async_stream::try_stream;
|
||||
|
||||
use hex;
|
||||
|
||||
pub fn full_extension(path: &Path) -> String {
|
||||
path.file_name()
|
||||
.and_then(|name| name.to_str())
|
||||
.map(|name| {
|
||||
match name.find('.') {
|
||||
Some(idx) => &name[idx..],
|
||||
None => "",
|
||||
}
|
||||
})
|
||||
.unwrap_or_default()
|
||||
.and_then(|n| n.to_str())
|
||||
.and_then(|n| n.find('.').map(|i| &n[i..]))
|
||||
.unwrap_or("")
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub async fn encrypt_file_stream(
|
||||
file_path: PathBuf,
|
||||
aes_key: [u8; 32],
|
||||
iv: [u8; 16],
|
||||
pub_key_pem: Vec<u8>,
|
||||
) -> Result<(impl Stream<Item = Result<Bytes>> + Send + 'static, String)> {
|
||||
// ---------- Encrypt AES key with RSA ----------
|
||||
let pkey = PKey::public_key_from_pem(&pub_key_pem)?;
|
||||
let mut rsa = Encrypter::new(&pkey)?;
|
||||
rsa.set_rsa_padding(Padding::PKCS1_OAEP)?;
|
||||
rsa.set_rsa_oaep_md(MessageDigest::sha256())?;
|
||||
rsa.set_rsa_mgf1_md(MessageDigest::sha256())?;
|
||||
|
||||
let mut encrypted_key = vec![0u8; rsa.encrypt_len(&aes_key)?];
|
||||
let len = rsa.encrypt(&aes_key, &mut encrypted_key)?;
|
||||
encrypted_key.truncate(len);
|
||||
|
||||
let encrypted_key_hex = hex::encode(encrypted_key);
|
||||
|
||||
// ---------- Streaming AES encryption ----------
|
||||
let stream = try_stream! {
|
||||
let file = File::open(&file_path).await?;
|
||||
let mut reader = BufReader::new(file);
|
||||
|
||||
let cipher = Cipher::aes_256_cbc();
|
||||
let mut crypter = Crypter::new(cipher, Mode::Encrypt, &aes_key, Some(&iv))?;
|
||||
crypter.pad(true);
|
||||
|
||||
let mut buffer = vec![0u8; 1024 * 1024]; // 1 MB chunks
|
||||
|
||||
loop {
|
||||
let n = reader.read(&mut buffer).await?;
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let mut out = vec![0u8; n + cipher.block_size()];
|
||||
let count = crypter.update(&buffer[..n], &mut out)?;
|
||||
out.truncate(count);
|
||||
|
||||
yield Bytes::from(out);
|
||||
}
|
||||
|
||||
let mut final_block = vec![0u8; cipher.block_size()];
|
||||
let rest = crypter.finalize(&mut final_block)?;
|
||||
final_block.truncate(rest);
|
||||
|
||||
if !final_block.is_empty() {
|
||||
yield Bytes::from(final_block);
|
||||
}
|
||||
};
|
||||
|
||||
Ok((stream, encrypted_key_hex))
|
||||
}
|
||||
Reference in New Issue
Block a user