feat: create harmony_composer initial version + rework CI (#58)
Co-authored-by: tahahawa <tahahawa@gmail.com> Reviewed-on: https://git.nationtech.io/NationTech/harmony/pulls/58 Reviewed-by: johnride <jg@nationtech.io> Co-authored-by: Taha Hawa <taha@taha.dev> Co-committed-by: Taha Hawa <taha@taha.dev>
This commit is contained in:
parent
7bebc58615
commit
155e9bac28
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
target/
|
||||||
|
Dockerfile
|
@ -1,11 +1,15 @@
|
|||||||
name: Run Check Script
|
name: Run Check Script
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
runs-on: rust-cargo
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: hub.nationtech.io/harmony/harmony_composer:latest@sha256:eb0406fcb95c63df9b7c4b19bc50ad7914dd8232ce98e9c9abef628e07c69386
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
46
.gitea/workflows/harmony_composer.yaml
Normal file
46
.gitea/workflows/harmony_composer.yaml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
name: Compile and package harmony_composer
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
package_harmony_composer:
|
||||||
|
container:
|
||||||
|
image: hub.nationtech.io/harmony/harmony_composer:latest@sha256:eb0406fcb95c63df9b7c4b19bc50ad7914dd8232ce98e9c9abef628e07c69386
|
||||||
|
runs-on: dind
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build for Linux x86_64
|
||||||
|
run: cargo build --release --bin harmony_composer --target x86_64-unknown-linux-gnu
|
||||||
|
|
||||||
|
- name: Build for Windows x86_64 GNU
|
||||||
|
run: cargo build --release --bin harmony_composer --target x86_64-pc-windows-gnu
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: binaries
|
||||||
|
path: |
|
||||||
|
target/x86_64-unknown-linux-gnu/release/harmony_composer
|
||||||
|
target/x86_64-pc-windows-gnu/release/harmony_composer.exe
|
||||||
|
|
||||||
|
- name: Setup log into hub.nationtech.io
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: hub.nationtech.io
|
||||||
|
username: ${{ secrets.HUB_BOT_USER }}
|
||||||
|
password: ${{ secrets.HUB_BOT_PASSWORD }}
|
||||||
|
|
||||||
|
# TODO: build ARM images and MacOS binaries (or other targets) too
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: hub.nationtech.io/harmony/harmony_composer:latest
|
297
Cargo.lock
generated
297
Cargo.lock
generated
@ -295,6 +295,51 @@ dependencies = [
|
|||||||
"cipher",
|
"cipher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bollard"
|
||||||
|
version = "0.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af706e9dc793491dd382c99c22fde6e9934433d4cc0d6a4b34eb2cdc57a5c917"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"bollard-stubs",
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"hex",
|
||||||
|
"http 1.3.1",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper 1.6.0",
|
||||||
|
"hyper-named-pipe",
|
||||||
|
"hyper-util",
|
||||||
|
"hyperlocal",
|
||||||
|
"log",
|
||||||
|
"pin-project-lite",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
|
"tower-service",
|
||||||
|
"url",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bollard-stubs"
|
||||||
|
version = "1.48.2-rc.28.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79cdf0fccd5341b38ae0be74b74410bdd5eceeea8876dc149a13edfe57e3b259"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"serde_with",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
@ -324,6 +369,55 @@ version = "1.10.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "camino"
|
||||||
|
version = "1.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo-platform"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84982c6c0ae343635a3a4ee6dedef965513735c8b183caa7289fa6e27399ebd4"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo-util-schemas"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e63d2780ac94487eb9f1fea7b0d56300abc9eb488800854ca217f102f5caccca"
|
||||||
|
dependencies = [
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde-untagged",
|
||||||
|
"serde-value",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
"toml",
|
||||||
|
"unicode-xid",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_metadata"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f7835cfc6135093070e95eb2b53e5d9b5c403dc3a6be6040ee026270aa82502"
|
||||||
|
dependencies = [
|
||||||
|
"camino",
|
||||||
|
"cargo-platform",
|
||||||
|
"cargo-util-schemas",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cassowary"
|
name = "cassowary"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -669,6 +763,12 @@ dependencies = [
|
|||||||
"cipher",
|
"cipher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "current_platform"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a74858bcfe44b22016cb49337d7b6f04618c58e5dbfdef61b06b8c434324a0bc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "curve25519-dalek"
|
name = "curve25519-dalek"
|
||||||
version = "4.1.3"
|
version = "4.1.3"
|
||||||
@ -755,6 +855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -980,6 +1081,16 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "erased-serde"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"typeid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.11"
|
version = "0.3.11"
|
||||||
@ -1391,7 +1502,7 @@ dependencies = [
|
|||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"indexmap",
|
"indexmap 2.9.0",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
@ -1410,7 +1521,7 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"http 1.3.1",
|
"http 1.3.1",
|
||||||
"indexmap",
|
"indexmap 2.9.0",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
@ -1476,6 +1587,21 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "harmony_composer"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bollard",
|
||||||
|
"cargo_metadata",
|
||||||
|
"clap",
|
||||||
|
"current_platform",
|
||||||
|
"env_logger",
|
||||||
|
"futures-util",
|
||||||
|
"log",
|
||||||
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "harmony_macros"
|
name = "harmony_macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -1513,6 +1639,12 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.3"
|
version = "0.15.3"
|
||||||
@ -1769,6 +1901,21 @@ dependencies = [
|
|||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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.6.0",
|
||||||
|
"hyper-util",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tower-service",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-rustls"
|
name = "hyper-rustls"
|
||||||
version = "0.27.5"
|
version = "0.27.5"
|
||||||
@ -1850,6 +1997,21 @@ dependencies = [
|
|||||||
"tracing",
|
"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.6.0",
|
||||||
|
"hyper-util",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.63"
|
version = "0.1.63"
|
||||||
@ -1993,6 +2155,17 @@ version = "0.3.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.9.0"
|
version = "2.9.0"
|
||||||
@ -2000,7 +2173,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown 0.15.3",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2338,7 +2512,7 @@ version = "0.12.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
|
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown 0.15.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3688,6 +3862,9 @@ name = "semver"
|
|||||||
version = "1.0.26"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
@ -3698,6 +3875,17 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-untagged"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e"
|
||||||
|
dependencies = [
|
||||||
|
"erased-serde",
|
||||||
|
"serde",
|
||||||
|
"typeid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde-value"
|
name = "serde-value"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -3741,6 +3929,26 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_tokenstream"
|
name = "serde_tokenstream"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@ -3765,13 +3973,30 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_with"
|
||||||
|
version = "3.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"chrono",
|
||||||
|
"hex",
|
||||||
|
"indexmap 1.9.3",
|
||||||
|
"indexmap 2.9.0",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_yaml"
|
name = "serde_yaml"
|
||||||
version = "0.9.34+deprecated"
|
version = "0.9.34+deprecated"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap 2.9.0",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
@ -4315,6 +4540,47 @@ dependencies = [
|
|||||||
"tokio",
|
"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 2.9.0",
|
||||||
|
"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]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
@ -4440,6 +4706,12 @@ dependencies = [
|
|||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typeid"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.18.0"
|
version = "1.18.0"
|
||||||
@ -4487,6 +4759,12 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "universal-hash"
|
name = "universal-hash"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -5024,6 +5302,15 @@ version = "0.53.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.50.0"
|
version = "0.50.0"
|
||||||
|
10
Cargo.toml
10
Cargo.toml
@ -11,6 +11,7 @@ members = [
|
|||||||
"opnsense-config-xml",
|
"opnsense-config-xml",
|
||||||
"harmony_cli",
|
"harmony_cli",
|
||||||
"k3d",
|
"k3d",
|
||||||
|
"harmony_composer",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
@ -23,7 +24,12 @@ log = "0.4.22"
|
|||||||
env_logger = "0.11.5"
|
env_logger = "0.11.5"
|
||||||
derive-new = "0.7.0"
|
derive-new = "0.7.0"
|
||||||
async-trait = "0.1.82"
|
async-trait = "0.1.82"
|
||||||
tokio = { version = "1.40.0", features = ["io-std", "fs", "macros", "rt-multi-thread"] }
|
tokio = { version = "1.40.0", features = [
|
||||||
|
"io-std",
|
||||||
|
"fs",
|
||||||
|
"macros",
|
||||||
|
"rt-multi-thread",
|
||||||
|
] }
|
||||||
cidr = { features = ["serde"], version = "0.2" }
|
cidr = { features = ["serde"], version = "0.2" }
|
||||||
russh = "0.45.0"
|
russh = "0.45.0"
|
||||||
russh-keys = "0.45.0"
|
russh-keys = "0.45.0"
|
||||||
@ -35,7 +41,7 @@ serde_yaml = "0.9.34"
|
|||||||
serde-value = "0.7.0"
|
serde-value = "0.7.0"
|
||||||
http = "1.2.0"
|
http = "1.2.0"
|
||||||
inquire = "0.7.5"
|
inquire = "0.7.5"
|
||||||
convert_case = "0.8.0"
|
convert_case = "0.8.0"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
|
||||||
[workspace.dependencies.uuid]
|
[workspace.dependencies.uuid]
|
||||||
|
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
FROM docker.io/rust:1.87.0 AS build
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN cargo build --release --bin harmony_composer
|
||||||
|
|
||||||
|
FROM docker.io/rust:1.87.0
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN rustup target add x86_64-pc-windows-gnu
|
||||||
|
RUN rustup target add x86_64-unknown-linux-gnu
|
||||||
|
RUN rustup component add rustfmt
|
||||||
|
|
||||||
|
RUN apt update
|
||||||
|
|
||||||
|
# TODO: Consider adding more supported targets
|
||||||
|
# nodejs for checkout action, docker for building containers, mingw for cross-compiling for windows
|
||||||
|
RUN apt install -y nodejs docker.io mingw-w64
|
||||||
|
|
||||||
|
COPY --from=build /app/target/release/harmony_composer .
|
||||||
|
|
||||||
|
ENTRYPOINT ["/app/harmony_composer"]
|
17
harmony_composer/Cargo.toml
Normal file
17
harmony_composer/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "harmony_composer"
|
||||||
|
edition = "2024"
|
||||||
|
version.workspace = true
|
||||||
|
readme.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "4.5.35", features = ["derive"] }
|
||||||
|
tokio.workspace = true
|
||||||
|
env_logger.workspace = true
|
||||||
|
log.workspace = true
|
||||||
|
bollard = "0.19.0"
|
||||||
|
current_platform = "0.2.0"
|
||||||
|
futures-util = "0.3.31"
|
||||||
|
serde_json = "1.0.140"
|
||||||
|
cargo_metadata = "0.20.0"
|
327
harmony_composer/src/main.rs
Normal file
327
harmony_composer/src/main.rs
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
use bollard::models::ContainerCreateBody;
|
||||||
|
use bollard::query_parameters::{
|
||||||
|
CreateContainerOptionsBuilder, ListContainersOptionsBuilder, LogsOptions,
|
||||||
|
RemoveContainerOptions, StartContainerOptions, WaitContainerOptions,
|
||||||
|
};
|
||||||
|
use bollard::secret::HostConfig;
|
||||||
|
use cargo_metadata::{Artifact, Message, MetadataCommand};
|
||||||
|
use clap::{Args, Parser, Subcommand};
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use log::info;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(version, about, long_about = None, flatten_help = true, propagate_version = true)]
|
||||||
|
struct GlobalArgs {
|
||||||
|
#[arg(long, default_value = "harmony")]
|
||||||
|
harmony_path: String,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
compile_method: Option<CompileMethod>,
|
||||||
|
|
||||||
|
#[arg(long)]
|
||||||
|
compile_platform: Option<String>,
|
||||||
|
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Option<Commands>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand, Clone, Debug)]
|
||||||
|
enum Commands {
|
||||||
|
Check(CheckArgs),
|
||||||
|
Compile,
|
||||||
|
Deploy(DeployArgs),
|
||||||
|
All(AllArgs),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Args, Clone, Debug)]
|
||||||
|
struct CheckArgs {
|
||||||
|
#[arg(long, default_value = "check.sh")]
|
||||||
|
check_script_path: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Args, Clone, Debug)]
|
||||||
|
struct DeployArgs {
|
||||||
|
#[arg(long, default_value_t = false)]
|
||||||
|
staging: bool,
|
||||||
|
|
||||||
|
#[arg(long, default_value_t = false)]
|
||||||
|
prod: bool,
|
||||||
|
|
||||||
|
#[arg(long, default_value_t = false)]
|
||||||
|
smoke_test: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Args, Clone, Debug)]
|
||||||
|
struct AllArgs {
|
||||||
|
#[command(flatten)]
|
||||||
|
check: CheckArgs,
|
||||||
|
|
||||||
|
#[command(flatten)]
|
||||||
|
deploy: DeployArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
env_logger::init();
|
||||||
|
let cli_args = GlobalArgs::parse();
|
||||||
|
|
||||||
|
let harmony_path = Path::new(&cli_args.harmony_path)
|
||||||
|
.try_exists()
|
||||||
|
.expect("couldn't check if path exists");
|
||||||
|
|
||||||
|
let harmony_bin_path: PathBuf;
|
||||||
|
match harmony_path {
|
||||||
|
true => {
|
||||||
|
harmony_bin_path = compile_harmony(
|
||||||
|
cli_args.compile_method,
|
||||||
|
cli_args.compile_platform,
|
||||||
|
cli_args.harmony_path.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
false => todo!("implement autodetect code"),
|
||||||
|
}
|
||||||
|
|
||||||
|
match cli_args.command {
|
||||||
|
Some(command) => match command {
|
||||||
|
Commands::Check(args) => {
|
||||||
|
let check_script_str =
|
||||||
|
format!("{}/{}", cli_args.harmony_path, args.check_script_path);
|
||||||
|
|
||||||
|
let check_script = Path::new(&check_script_str);
|
||||||
|
|
||||||
|
match check_script
|
||||||
|
.try_exists()
|
||||||
|
.expect("couldn't check if path exists")
|
||||||
|
{
|
||||||
|
true => (),
|
||||||
|
false => todo!("implement couldn't find path logic"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let check_output = Command::new(check_script)
|
||||||
|
.output()
|
||||||
|
.expect("failed to run check script");
|
||||||
|
info!(
|
||||||
|
"check stdout: {}, check stderr: {}",
|
||||||
|
String::from_utf8(check_output.stdout).expect("couldn't parse from utf8"),
|
||||||
|
String::from_utf8(check_output.stderr).expect("couldn't parse from utf8")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Commands::Deploy(args) => {
|
||||||
|
if args.staging {
|
||||||
|
todo!("implement staging deployment");
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.prod {
|
||||||
|
todo!("implement prod deployment");
|
||||||
|
}
|
||||||
|
let deploy_output = Command::new(harmony_bin_path)
|
||||||
|
.arg("-y")
|
||||||
|
.arg("-a")
|
||||||
|
.output()
|
||||||
|
.expect("failed to run harmony deploy");
|
||||||
|
println!(
|
||||||
|
"deploy output: {}",
|
||||||
|
String::from_utf8(deploy_output.stdout).expect("couldn't parse from utf8")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Commands::All(_args) => todo!(
|
||||||
|
"take all previous match arms and turn them into separate functions, and call them all one after the other"
|
||||||
|
),
|
||||||
|
Commands::Compile => return,
|
||||||
|
},
|
||||||
|
None => todo!("run interactively, ask for info on CLI"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, clap::ValueEnum)]
|
||||||
|
enum CompileMethod {
|
||||||
|
LocalCargo,
|
||||||
|
Docker,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn compile_harmony(
|
||||||
|
method: Option<CompileMethod>,
|
||||||
|
platform: Option<String>,
|
||||||
|
harmony_location: String,
|
||||||
|
) -> PathBuf {
|
||||||
|
let platform = match platform {
|
||||||
|
Some(p) => p,
|
||||||
|
None => current_platform::CURRENT_PLATFORM.to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let cargo_exists = Command::new("which")
|
||||||
|
.arg("cargo")
|
||||||
|
.status()
|
||||||
|
.expect("couldn't get `which cargo` status")
|
||||||
|
.success();
|
||||||
|
|
||||||
|
let method = match method {
|
||||||
|
Some(m) => m,
|
||||||
|
None => {
|
||||||
|
if cargo_exists {
|
||||||
|
return compile_cargo(platform, harmony_location).await;
|
||||||
|
} else {
|
||||||
|
return compile_docker(platform, harmony_location).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match method {
|
||||||
|
CompileMethod::LocalCargo => return compile_cargo(platform, harmony_location).await,
|
||||||
|
CompileMethod::Docker => return compile_docker(platform, harmony_location).await,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make sure this works with cargo workspaces
|
||||||
|
async fn compile_cargo(platform: String, harmony_location: String) -> PathBuf {
|
||||||
|
let metadata = MetadataCommand::new()
|
||||||
|
.manifest_path(format!("{}/Cargo.toml", harmony_location))
|
||||||
|
.exec()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut cargo_build = Command::new("cargo")
|
||||||
|
.current_dir(&harmony_location)
|
||||||
|
.args(vec![
|
||||||
|
"build",
|
||||||
|
format!("--target={}", platform).as_str(),
|
||||||
|
"--release",
|
||||||
|
"--message-format=json-render-diagnostics",
|
||||||
|
])
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect("run cargo command failed");
|
||||||
|
|
||||||
|
let mut artifacts: Vec<Artifact> = vec![];
|
||||||
|
let reader = std::io::BufReader::new(cargo_build.stdout.take().unwrap());
|
||||||
|
for message in cargo_metadata::Message::parse_stream(reader) {
|
||||||
|
match message.unwrap() {
|
||||||
|
Message::CompilerMessage(_msg) => (),
|
||||||
|
Message::CompilerArtifact(artifact) => {
|
||||||
|
if artifact.manifest_path
|
||||||
|
== metadata
|
||||||
|
.root_package()
|
||||||
|
.expect("failed to get root package")
|
||||||
|
.manifest_path
|
||||||
|
{
|
||||||
|
println!("{:?}", artifact);
|
||||||
|
artifacts.push(artifact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::BuildScriptExecuted(_script) => (),
|
||||||
|
Message::BuildFinished(finished) => {
|
||||||
|
println!("{:?}", finished);
|
||||||
|
}
|
||||||
|
_ => (), // Unknown message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let bin = artifacts
|
||||||
|
.last()
|
||||||
|
.expect("no binaries built")
|
||||||
|
.filenames
|
||||||
|
.first()
|
||||||
|
.expect("couldn't get filename");
|
||||||
|
|
||||||
|
let bin_out;
|
||||||
|
if let Some(ext) = bin.extension() {
|
||||||
|
bin_out = PathBuf::from(format!("{}/harmony.{}", harmony_location, ext));
|
||||||
|
let _copy_res = fs::copy(&bin, &bin_out).await;
|
||||||
|
} else {
|
||||||
|
bin_out = PathBuf::from(format!("{}/harmony", harmony_location));
|
||||||
|
let _copy_res = fs::copy(&bin, &bin_out).await;
|
||||||
|
}
|
||||||
|
return bin_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn compile_docker(platform: String, harmony_location: String) -> PathBuf {
|
||||||
|
let docker_client =
|
||||||
|
bollard::Docker::connect_with_local_defaults().expect("couldn't connect to docker");
|
||||||
|
|
||||||
|
let mut filters = HashMap::new();
|
||||||
|
filters.insert(String::from("name"), vec![String::from("harmony_build")]);
|
||||||
|
let list_containers_options = ListContainersOptionsBuilder::new()
|
||||||
|
.all(true)
|
||||||
|
.filters(&filters)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let containers = &docker_client
|
||||||
|
.list_containers(Some(list_containers_options))
|
||||||
|
.await
|
||||||
|
.expect("list containers failed");
|
||||||
|
|
||||||
|
if containers.len() > 0 {
|
||||||
|
docker_client
|
||||||
|
.remove_container("harmony_build", None::<RemoveContainerOptions>)
|
||||||
|
.await
|
||||||
|
.expect("failed to remove container");
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = Some(
|
||||||
|
CreateContainerOptionsBuilder::new()
|
||||||
|
.name("harmony_build")
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let config = ContainerCreateBody {
|
||||||
|
image: Some("hub.nationtech.io/harmony/harmony_composer".to_string()),
|
||||||
|
working_dir: Some("/mnt".to_string()),
|
||||||
|
cmd: Some(vec![
|
||||||
|
format!("--compile-platform={}", platform),
|
||||||
|
format!("--harmony-path=/mnt"),
|
||||||
|
"compile".to_string(),
|
||||||
|
]),
|
||||||
|
host_config: Some(HostConfig {
|
||||||
|
binds: Some(vec![format!("{}:/mnt", harmony_location)]),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
docker_client
|
||||||
|
.create_container(options, config)
|
||||||
|
.await
|
||||||
|
.expect("couldn't create container");
|
||||||
|
|
||||||
|
docker_client
|
||||||
|
.start_container("harmony_build", None::<StartContainerOptions>)
|
||||||
|
.await
|
||||||
|
.expect("couldn't start container");
|
||||||
|
|
||||||
|
let wait_options = WaitContainerOptions {
|
||||||
|
condition: "not-running".to_string(),
|
||||||
|
};
|
||||||
|
let mut wait = docker_client
|
||||||
|
.wait_container("harmony_build", Some(wait_options))
|
||||||
|
.boxed();
|
||||||
|
|
||||||
|
let mut logs_stream = docker_client.logs(
|
||||||
|
"harmony_build",
|
||||||
|
Some(LogsOptions {
|
||||||
|
follow: true,
|
||||||
|
stdout: true,
|
||||||
|
stderr: true,
|
||||||
|
tail: "all".to_string(),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
while let Some(l) = logs_stream.next().await {
|
||||||
|
let l_str = l.expect("couldn't unwrap logoutput").to_string();
|
||||||
|
println!("{}", l_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait until container is no longer running
|
||||||
|
while let Some(_) = wait.next().await {}
|
||||||
|
|
||||||
|
// hack that should be cleaned up
|
||||||
|
if platform.contains("windows") {
|
||||||
|
return PathBuf::from(format!("{}/harmony.exe", harmony_location));
|
||||||
|
} else {
|
||||||
|
return PathBuf::from(format!("{}/harmony", harmony_location));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user