mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 17:14:08 +02:00
Compare commits
39 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a38de3fdee | |||
| d138740bbd | |||
| fc6cde4161 | |||
| a3f2355dea | |||
| d852f9db4f | |||
| 92fbc74a5b | |||
| 204fb676d6 | |||
| f99238121b | |||
| cd9740675f | |||
| 39ba7a2a53 | |||
| ad999702aa | |||
| b977cd9dfa | |||
| 8771e7dc5f | |||
| 373ce0f3fd | |||
| 9e080f0d54 | |||
| 512b669a7c | |||
| ea3f89bb04 | |||
| b4a77997ab | |||
| 87f6907778 | |||
| 9de626a905 | |||
| 53e30a94aa | |||
| 948d01600e | |||
| 19e60217ea | |||
| 96b7dd671c | |||
| 24b8fd26ca | |||
| 814a1c3121 | |||
| a1ed0571be | |||
| 0a16737398 | |||
| 266b70339b | |||
| 3abf183ae3 | |||
| a80354c922 | |||
| 3b4014b5e4 | |||
| 4ab23610a2 | |||
| 0d98667650 | |||
| ce34f302a1 | |||
| 63e17d609f | |||
| 6fdadd9bad | |||
| 0105c60a09 | |||
| 85ffdcea5a |
58 changed files with 1222 additions and 553 deletions
|
|
@ -4,6 +4,7 @@ on:
|
||||||
push:
|
push:
|
||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
paths:
|
paths:
|
||||||
|
- "Cargo.toml"
|
||||||
- ".forgejo/workflows/docker.yaml"
|
- ".forgejo/workflows/docker.yaml"
|
||||||
- "nix/image/**"
|
- "nix/image/**"
|
||||||
|
|
||||||
|
|
@ -16,10 +17,9 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
php-version: ["8.0", "8,1", "8.2", "8.3", "8.4", "8.5"]
|
php-version: ["8.0", "8.1", "8.2", "8.3", "8.4", "8.5"]
|
||||||
variant: [""]
|
|
||||||
|
|
||||||
name: haze-${{ matrix.php-version }}${{ matrix.variant }}
|
name: haze-${{ matrix.php-version }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
|
|
||||||
198
Cargo.lock
generated
198
Cargo.lock
generated
|
|
@ -25,7 +25,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cipher",
|
"cipher",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -147,6 +147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
|
checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum-core",
|
"axum-core",
|
||||||
|
"axum-macros",
|
||||||
"bytes",
|
"bytes",
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
|
@ -192,6 +193,17 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "axum-macros"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.74"
|
version = "0.3.74"
|
||||||
|
|
@ -254,9 +266,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bollard"
|
name = "bollard"
|
||||||
version = "0.20.1"
|
version = "0.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "227aa051deec8d16bd9c34605e7aaf153f240e35483dd42f6f78903847934738"
|
checksum = "c9d0a013e3d3ee4edd61e779adf117944c08902d375f18630a0c5b8f95659734"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bollard-stubs",
|
"bollard-stubs",
|
||||||
|
|
@ -286,9 +298,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bollard-stubs"
|
name = "bollard-stubs"
|
||||||
version = "1.52.1-rc.29.1.3"
|
version = "1.53.1-rc.29.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f0a8ca8799131c1837d1282c3f81f31e76ceb0ce426e04a7fe1ccee3287c066"
|
checksum = "ce412eb6f7096743011dc3cb5c674caeb24ced61d8c498fe07cf7998a4fea889"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
@ -372,6 +384,17 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.0",
|
||||||
|
"rand_core 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cipher"
|
name = "cipher"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
|
@ -497,6 +520,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
|
@ -506,6 +538,31 @@ dependencies = [
|
||||||
"cfg-if",
|
"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-utils"
|
||||||
|
version = "0.8.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
|
@ -860,6 +917,7 @@ dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"r-efi",
|
"r-efi",
|
||||||
|
"rand_core 0.10.1",
|
||||||
"wasip2",
|
"wasip2",
|
||||||
"wasip3",
|
"wasip3",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
|
@ -885,34 +943,14 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "git2"
|
name = "git2"
|
||||||
version = "0.20.4"
|
version = "0.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b"
|
checksum = "ddddbf932745a6be37109b6112d3ee09696106f848449069d3a57bba937ab82e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"libc",
|
"libc",
|
||||||
"libgit2-sys",
|
"libgit2-sys",
|
||||||
"log",
|
"log",
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "h2"
|
|
||||||
version = "0.4.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
|
|
||||||
dependencies = [
|
|
||||||
"atomic-waker",
|
|
||||||
"bytes",
|
|
||||||
"fnv",
|
|
||||||
"futures-core",
|
|
||||||
"futures-sink",
|
|
||||||
"http",
|
|
||||||
"indexmap",
|
|
||||||
"slab",
|
|
||||||
"tokio",
|
|
||||||
"tokio-util",
|
|
||||||
"tracing",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -932,7 +970,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "haze"
|
name = "haze"
|
||||||
version = "2.2.0"
|
version = "2.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"atty",
|
"atty",
|
||||||
|
|
@ -956,6 +994,7 @@ dependencies = [
|
||||||
"opener",
|
"opener",
|
||||||
"owo-colors",
|
"owo-colors",
|
||||||
"petname",
|
"petname",
|
||||||
|
"rayon",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
@ -965,6 +1004,7 @@ dependencies = [
|
||||||
"tar",
|
"tar",
|
||||||
"termion",
|
"termion",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
"toml",
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
|
|
@ -1072,7 +1112,6 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"h2",
|
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"httparse",
|
"httparse",
|
||||||
|
|
@ -1103,8 +1142,9 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-reverse-proxy"
|
name = "hyper-reverse-proxy"
|
||||||
version = "0.5.2-dev"
|
version = "0.5.2-dev"
|
||||||
source = "git+https://github.com/chpio/hyper-reverse-proxy?rev=6934877eb74465204f605cc1c05ca5a9772db7c0#6934877eb74465204f605cc1c05ca5a9772db7c0"
|
source = "git+https://code.betamike.com/micropelago/hyper-reverse-proxy.git?rev=d5a6f799189360d9449ae47ab3cdde511f02cf39#d5a6f799189360d9449ae47ab3cdde511f02cf39"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"http-body-util",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|
@ -1471,9 +1511,9 @@ checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libgit2-sys"
|
name = "libgit2-sys"
|
||||||
version = "0.18.3+1.9.2"
|
version = "0.18.5+1.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487"
|
checksum = "005d6ae6eac1912906073e069f7db60b1fa98e052a68227824afe3e3a1c59ca2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -1774,16 +1814,24 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "petname"
|
name = "petname"
|
||||||
version = "2.0.2"
|
version = "3.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9cd31dcfdbbd7431a807ef4df6edd6473228e94d5c805e8cf671227a21bad068"
|
checksum = "2ce610bff48dd7b6a127e45631795fbb0b302b99a39bef7e6da3d297e8eb2b6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"clap",
|
"clap",
|
||||||
"itertools",
|
"petname-macros",
|
||||||
|
"rand 0.10.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "petname-macros"
|
||||||
|
version = "3.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "324239bd00dcf61f1a0e301d4d8f6f8c080a755248fc3fdc817ee1fdbbc27b8b"
|
||||||
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rand 0.8.5",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1943,35 +1991,25 @@ version = "5.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||||
|
|
||||||
[[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]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha 0.9.0",
|
"rand_chacha",
|
||||||
"rand_core 0.9.5",
|
"rand_core 0.9.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand"
|
||||||
version = "0.3.1"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"chacha20",
|
||||||
"rand_core 0.6.4",
|
"getrandom 0.4.1",
|
||||||
|
"rand_core 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1984,15 +2022,6 @@ dependencies = [
|
||||||
"rand_core 0.9.5",
|
"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.15",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_core"
|
name = "rand_core"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
|
|
@ -2002,6 +2031,32 @@ dependencies = [
|
||||||
"getrandom 0.3.4",
|
"getrandom 0.3.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
||||||
|
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]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.10"
|
version = "0.5.10"
|
||||||
|
|
@ -2334,7 +2389,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest 0.10.7",
|
"digest 0.10.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2345,7 +2400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest 0.10.7",
|
"digest 0.10.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2356,7 +2411,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024"
|
checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest 0.11.1",
|
"digest 0.11.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2695,6 +2750,17 @@ dependencies = [
|
||||||
"tokio",
|
"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]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.13"
|
version = "0.7.13"
|
||||||
|
|
|
||||||
14
Cargo.toml
14
Cargo.toml
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "haze"
|
name = "haze"
|
||||||
version = "2.2.0"
|
version = "2.3.0"
|
||||||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://codeberg.org/icewind/haze"
|
repository = "https://codeberg.org/icewind/haze"
|
||||||
|
|
@ -8,10 +8,11 @@ license = "MIT"
|
||||||
description = "Easy setup and management of Nextcloud test instances using docker"
|
description = "Easy setup and management of Nextcloud test instances using docker"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bollard = "0.20.1"
|
bollard = "0.21.0"
|
||||||
maplit = "1.0.2"
|
maplit = "1.0.2"
|
||||||
camino = { version = "1.2.2", features = ["serde1"] }
|
camino = { version = "1.2.2", features = ["serde1"] }
|
||||||
tokio = { version = "1.49.0", features = ["fs", "macros", "signal", "rt-multi-thread"] }
|
tokio = { version = "1.49.0", features = ["fs", "macros", "signal", "rt-multi-thread"] }
|
||||||
|
tokio-stream = { version = "0.1.18", features = ["net"] }
|
||||||
futures-util = "0.3.32"
|
futures-util = "0.3.32"
|
||||||
termion = "4.0.6"
|
termion = "4.0.6"
|
||||||
opener = "0.8.4"
|
opener = "0.8.4"
|
||||||
|
|
@ -19,7 +20,7 @@ toml = "1.0.3"
|
||||||
directories-next = "2.0.0"
|
directories-next = "2.0.0"
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
petname = "2.0.2"
|
petname = "3.0.0"
|
||||||
reqwest = { version = "0.13.2", default-features = false, features = ["rustls"] }
|
reqwest = { version = "0.13.2", default-features = false, features = ["rustls"] }
|
||||||
tar = "0.4.44"
|
tar = "0.4.44"
|
||||||
flate2 = "1.1.9"
|
flate2 = "1.1.9"
|
||||||
|
|
@ -30,7 +31,7 @@ shell-words = "1.1.1"
|
||||||
tracing = "0.1.44"
|
tracing = "0.1.44"
|
||||||
tracing-subscriber = "0.3.22"
|
tracing-subscriber = "0.3.22"
|
||||||
atty = "0.2.14"
|
atty = "0.2.14"
|
||||||
git2 = { version = "0.20.4", default-features = false }
|
git2 = { version = "0.21.0", default-features = false }
|
||||||
itertools = { version = "0.14.0", features = ["use_alloc"] }
|
itertools = { version = "0.14.0", features = ["use_alloc"] }
|
||||||
local-ip-address = "0.6.10"
|
local-ip-address = "0.6.10"
|
||||||
strum = { version = "0.28.0", features = ["derive"] }
|
strum = { version = "0.28.0", features = ["derive"] }
|
||||||
|
|
@ -39,11 +40,12 @@ zip = "8.1.0"
|
||||||
sha2 = "0.11.0-rc.5"
|
sha2 = "0.11.0-rc.5"
|
||||||
base16ct = { version = "1.0.0", features = ["alloc"] }
|
base16ct = { version = "1.0.0", features = ["alloc"] }
|
||||||
indicatif = "0.18.4"
|
indicatif = "0.18.4"
|
||||||
|
rayon = "1.12.0"
|
||||||
|
|
||||||
hyper-reverse-proxy = { version = "0.5.2-dev", git = "https://github.com/chpio/hyper-reverse-proxy", rev = "6934877eb74465204f605cc1c05ca5a9772db7c0" }
|
hyper-reverse-proxy = { version = "0.5.2-dev", git = "https://code.betamike.com/micropelago/hyper-reverse-proxy.git", rev = "d5a6f799189360d9449ae47ab3cdde511f02cf39" }
|
||||||
hyper = "1.8.1"
|
hyper = "1.8.1"
|
||||||
hyper-util = "0.1.20"
|
hyper-util = "0.1.20"
|
||||||
axum = { version = "0.8.8", features = ["tokio"] }
|
axum = { version = "0.8.8", features = ["tokio", "macros"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
|
|
||||||
14
README.md
14
README.md
|
|
@ -81,6 +81,8 @@ Additionally, you can use the following options when starting an instance:
|
||||||
- `smb`: set up a samba server for external storage use.
|
- `smb`: set up a samba server for external storage use.
|
||||||
- `dav`: set up a WebDAV server for external storage use.
|
- `dav`: set up a WebDAV server for external storage use.
|
||||||
- `sftp`: set up a SFTP server for external storage use.
|
- `sftp`: set up a SFTP server for external storage use.
|
||||||
|
- `sftp-key`: set up a SFTP server for external storage use with public key
|
||||||
|
authentication.
|
||||||
- `kaspersky`: set up a kaspersky scan engine server in http mode. ( Requires
|
- `kaspersky`: set up a kaspersky scan engine server in http mode. ( Requires
|
||||||
[manually setting up the image](https://github.com/icewind1991/kaspersky-docker))
|
[manually setting up the image](https://github.com/icewind1991/kaspersky-docker))
|
||||||
- `kaspersky-icap`: setup a kaspersky scan engine server in ICAP mode.
|
- `kaspersky-icap`: setup a kaspersky scan engine server in ICAP mode.
|
||||||
|
|
@ -93,6 +95,8 @@ Additionally, you can use the following options when starting an instance:
|
||||||
generation.
|
generation.
|
||||||
- `mail`: start a [smtp4dev](https://github.com/rnwood/smtp4dev) server and
|
- `mail`: start a [smtp4dev](https://github.com/rnwood/smtp4dev) server and
|
||||||
configure it the mail server.
|
configure it the mail server.
|
||||||
|
- `webhook` start a
|
||||||
|
[webhook tester](https://github.com/tarampampam/webhook-tester)
|
||||||
- `redis`: start a separate container for redis.
|
- `redis`: start a separate container for redis.
|
||||||
- `redis-tls`: connect to redis over TLS.
|
- `redis-tls`: connect to redis over TLS.
|
||||||
- `<path to app.tar.gz>`: by specifying the path to an app package this package
|
- `<path to app.tar.gz>`: by specifying the path to an app package this package
|
||||||
|
|
@ -147,11 +151,14 @@ haze [match] db
|
||||||
#### Execute a command on an instance
|
#### Execute a command on an instance
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
haze [match] exec [cmd]
|
haze [match] [service] [cmd]
|
||||||
```
|
```
|
||||||
|
|
||||||
If no `cmd` is specified it will launch `bash`
|
If no `cmd` is specified it will launch `bash`
|
||||||
|
|
||||||
|
If a service name or `db` is provided, the command will be in the container of
|
||||||
|
the service or database.
|
||||||
|
|
||||||
#### Create a new instance and run a command
|
#### Create a new instance and run a command
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -274,8 +281,7 @@ proxy to allow using a wildcard domain.
|
||||||
### Setup
|
### Setup
|
||||||
|
|
||||||
- Set a DNS record for `*.haze.exmaple.com` and `haze.example.com` pointing to
|
- Set a DNS record for `*.haze.exmaple.com` and `haze.example.com` pointing to
|
||||||
your development machine. Pointing it to `127.0.0.1` will also work, but comes
|
your development machine.
|
||||||
with limitations like federation not being supported.
|
|
||||||
- Set the `proxy` configuration with your domain and desired listen endpoint.
|
- Set the `proxy` configuration with your domain and desired listen endpoint.
|
||||||
- Set up a service to run `haze proxy` in the background as your own user. A
|
- Set up a service to run `haze proxy` in the background as your own user. A
|
||||||
systemd user service is recommended (see [haze.service](./haze.service) for an
|
systemd user service is recommended (see [haze.service](./haze.service) for an
|
||||||
|
|
@ -296,7 +302,7 @@ will automatically point to the last created instance.
|
||||||
|
|
||||||
Additionally, the proxy allows access to the server containers trough either
|
Additionally, the proxy allows access to the server containers trough either
|
||||||
`<instance id>-<service id>.haze.example.com` for a specific instance, or
|
`<instance id>-<service id>.haze.example.com` for a specific instance, or
|
||||||
`<service-id>.haze.example.com` for the last created instead. For example
|
`<service-id>.haze.example.com` for the last created instance. For example
|
||||||
`rolling-bees-mail.haze.example.com` will give access to the smtp4dev web
|
`rolling-bees-mail.haze.example.com` will give access to the smtp4dev web
|
||||||
interface of the `rolling-bees` instance.
|
interface of the `rolling-bees` instance.
|
||||||
|
|
||||||
|
|
|
||||||
38
certificates/sftp/id_rsa
Normal file
38
certificates/sftp/id_rsa
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||||
|
NhAAAAAwEAAQAAAYEA323aWqH6YwRLbCBO94UKOkfnJ2m6Zsic0dMt3TmDnjLU0JzpOt7w
|
||||||
|
t5+mMZrEKQTpefozyUHo3z+HkmllLAGOupNy3A+jG2O955UUgw0dGfu6j6OOb66Du9jpqt
|
||||||
|
8BQ6gr3cEYASplPI7B889/cVpJ5l1HiBUgyR7Z16v15qCDtmpFVIECAdICEmPosfmZutt3
|
||||||
|
YYl9xLay5WCmUztWS/amPcGs0DOEGrWeCtdxGKWT3TywdBKyQ0PbdYMamgDIT7JV1ZSzZP
|
||||||
|
aly4sB7E+dpS5AgBFVXmZ61151KN1TJ8gyoUjFhY7ctYEIpncZmyT4PYvyIvxRsbJtvERi
|
||||||
|
eNH8DoX5DwtqcxbgHK0OwYtdl4ydRXToYo3l+qIidf+g8ADVea/mbkfTPegdToo3LOuThX
|
||||||
|
OwExDlukpM8obFDpz1Yl1L6rRJAVNO1KmHWhn6to23jtYjBhczA2nkemQXQbVSjc/hItjQ
|
||||||
|
DIFNMOsLW33P+Y2k9LkpI0TL09ogOxOFZzGZp2tNAAAFgIgMIZ+IDCGfAAAAB3NzaC1yc2
|
||||||
|
EAAAGBAN9t2lqh+mMES2wgTveFCjpH5ydpumbInNHTLd05g54y1NCc6Tre8LefpjGaxCkE
|
||||||
|
6Xn6M8lB6N8/h5JpZSwBjrqTctwPoxtjveeVFIMNHRn7uo+jjm+ug7vY6arfAUOoK93BGA
|
||||||
|
EqZTyOwfPPf3FaSeZdR4gVIMke2der9eagg7ZqRVSBAgHSAhJj6LH5mbrbd2GJfcS2suVg
|
||||||
|
plM7Vkv2pj3BrNAzhBq1ngrXcRilk908sHQSskND23WDGpoAyE+yVdWUs2T2pcuLAexPna
|
||||||
|
UuQIARVV5metdedSjdUyfIMqFIxYWO3LWBCKZ3GZsk+D2L8iL8UbGybbxEYnjR/A6F+Q8L
|
||||||
|
anMW4BytDsGLXZeMnUV06GKN5fqiInX/oPAA1Xmv5m5H0z3oHU6KNyzrk4VzsBMQ5bpKTP
|
||||||
|
KGxQ6c9WJdS+q0SQFTTtSph1oZ+raNt47WIwYXMwNp5HpkF0G1Uo3P4SLY0AyBTTDrC1t9
|
||||||
|
z/mNpPS5KSNEy9PaIDsThWcxmadrTQAAAAMBAAEAAAGAWCkM/TEnztU9e3M+JX253OhNRe
|
||||||
|
h6lB75ffOxh7avgAc3oP8hKkkYu6PDnJQgbb0R8T7wGywmGp0DPhrXQGd27ZjLvBhxeBfB
|
||||||
|
sbTJ7LIKdxu0cAQN6nR2Z3M+NF2dLpiXgn80HRWg76W20yDffRcuzLamyIPptWI2e9rPAw
|
||||||
|
r4HczOAXuMErLOfXotsbg22BvL/dEWLr4WVdruli32LbArxXd73IVPTYi3TTjYV+zRrPzK
|
||||||
|
9WoBK/iFClfKcdT4NTY82llQesuUNu640lEJtT2G3Iba8UZnohyzm/S+UbeU65z8DKD5co
|
||||||
|
P7+QehxQSV+kj2BZnTi0WEwsD+GTznJYR5rvUsJCCAzoISsWrncSSgOQhF2XeW/T4ewvH+
|
||||||
|
njLZViEhdG8R3kkdDjJG91OrSgrEqlk6Qhz1xEsv1rCOR69En7EJP3TNNrymPXPASrAnuE
|
||||||
|
HQkrVgGUfGqyD1sw1e6nBfNWisuw+g99CieIB8EI9WwpxQdKqWNU9Hjx+SAdC3NrPjAAAA
|
||||||
|
wQCo0hUGjSf6xhcgeaNa0gWSKEVuFhxR/FaCPTKadV7Md0APW4toeQZDujzDFlCZbQTZjC
|
||||||
|
0723B4lKugDzXfsOgvOTKp4vEjZOu0YGruS00LFWM7Sutdzx68b/ZMFALzITt/myKVMdpv
|
||||||
|
WpaO+3+PyEYIQH44QrSWw7cKLzNiZ8kt2drPkPktub4o2h5TdIBluEQLJDPMejy8IqQEU8
|
||||||
|
aOyJOMvYxAbGAWY7Ck9DGlcJgaFdORROW8d8ZGrHQkyRl41JQAAADBAPeUMsrbI17wPP/s
|
||||||
|
Tsrkms5ws5yTz0xle2Wn6HwDSzQRSdn5abnIDYb3QSy0nRBvczef6ssH65dl50+2V4BV2L
|
||||||
|
MwHcmKD6/UoFsWwP/RMf1EoacPFiEAWJGxFbOthNX+rx5BpbUHNoQd8xby+88saDI0e8W6
|
||||||
|
36HPBZrAZhQljkMa4OJqZDDCpOJvSndXwkZ789E96uprKopJZGwlLmfMtikQpNXT9R+I0b
|
||||||
|
SQCJj4yNakcdOE/7UifkOR02u+pgux3wAAAMEA5wdelKwGQ0EdkIF2TM844uLPszo3ZSH+
|
||||||
|
Heff/Lbxs1Y+oL0NTJQicwMF0d9WEwBoTZJpuzsQEA1zkfmW0gi2womIRmiY0ZhpxbBuhO
|
||||||
|
6XePMIhUfQmWWjaUbAkrNB0eJkSTuUGzwxVkMXehrMuj4gYe8GMC8GgULbP0A8FjH01fKk
|
||||||
|
jFwgg4WAg6zUTpck12bh49NZRFyXIbXNk/jjxJtb0p//5TRTUQ6mR5IloaNTM23EiF6tle
|
||||||
|
Y6CAchnyhHO0BTAAAACWhhemVAaGF6ZQE=
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
1
certificates/sftp/id_rsa.pub
Normal file
1
certificates/sftp/id_rsa.pub
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDfbdpaofpjBEtsIE73hQo6R+cnabpmyJzR0y3dOYOeMtTQnOk63vC3n6YxmsQpBOl5+jPJQejfP4eSaWUsAY66k3LcD6MbY73nlRSDDR0Z+7qPo45vroO72Omq3wFDqCvdwRgBKmU8jsHzz39xWknmXUeIFSDJHtnXq/XmoIO2akVUgQIB0gISY+ix+Zm623dhiX3EtrLlYKZTO1ZL9qY9wazQM4QatZ4K13EYpZPdPLB0ErJDQ9t1gxqaAMhPslXVlLNk9qXLiwHsT52lLkCAEVVeZnrXXnUo3VMnyDKhSMWFjty1gQimdxmbJPg9i/Ii/FGxsm28RGJ40fwOhfkPC2pzFuAcrQ7Bi12XjJ1FdOhijeX6oiJ1/6DwANV5r+ZuR9M96B1Oijcs65OFc7ATEOW6SkzyhsUOnPViXUvqtEkBU07UqYdaGfq2jbeO1iMGFzMDaeR6ZBdBtVKNz+Ei2NAMgU0w6wtbfc/5jaT0uSkjRMvT2iA7E4VnMZmna00= haze@haze
|
||||||
88
nix/image/bootstrap
Executable file
88
nix/image/bootstrap
Executable file
|
|
@ -0,0 +1,88 @@
|
||||||
|
#!/bin/nu
|
||||||
|
|
||||||
|
touch /var/log/nginx/access.log
|
||||||
|
touch /var/log/nginx/error.log
|
||||||
|
touch /var/log/cron/owncloud.log
|
||||||
|
|
||||||
|
mkdir /config
|
||||||
|
echo "# Options in here overwrite the builtin php.ini\n" | save /config/php.ini
|
||||||
|
echo "# xdebug.mode = debug\n" | save -a /config/php.ini
|
||||||
|
echo "# xdebug.start_with_request = yes\n\n" | save -a /config/php.ini
|
||||||
|
chmod 0777 /config/php.ini
|
||||||
|
let PHP_INI_DIR = php --ini | grep 'Scan' | cut -d ' ' -f7 | tr -d '"'
|
||||||
|
ln -s /config/php.ini $"($PHP_INI_DIR)/zz_extra.ini"
|
||||||
|
|
||||||
|
let HAZE_UID = $env.HAZE_UID | default "1000"
|
||||||
|
let HAZE_GID = $env.HAZE_GID | default "1000"
|
||||||
|
|
||||||
|
nc-auto-config
|
||||||
|
shadow-setup
|
||||||
|
|
||||||
|
echo $"Running as ($HAZE_UID):($HAZE_GID)"
|
||||||
|
|
||||||
|
mkdir /var/www/html/core/skeleton /var/www/html/build/integration/vendor /var/www/html/build/integration/output /var/www/html/build/integration/work /var/www/html/core/skeleton /var/www/.composer/cache /var/www/html/apps/spreed/tests/integration/vendor/composer
|
||||||
|
chown -R $"($HAZE_UID):($HAZE_GID)" /var/www/html/data /var/www/html/config
|
||||||
|
chown $"($HAZE_UID):($HAZE_GID)" /var/www/html/core/skeleton /var/www/html/build/integration/vendor /var/www/html/build/integration/composer.lock /var/www/html/build/integration/output /var/www/html/build/integration/work /var/www/html/core/skeleton /var/www/.composer/cache /var/www/html/apps/spreed/tests/integration/vendor/composer
|
||||||
|
|
||||||
|
echo "{}\n" | save -f /var/www/html/build/integration/composer.lock
|
||||||
|
|
||||||
|
echo $"Starting server using ($env.SQL) database…"
|
||||||
|
|
||||||
|
chmod +sx /sbin/sudo
|
||||||
|
|
||||||
|
mkdir /var/log/nginx /tmp /var/run/blackfire
|
||||||
|
touch /var/log/nginx/access.log
|
||||||
|
touch /var/log/nginx/error.log
|
||||||
|
|
||||||
|
if ((getent group $HAZE_GID | length) > 0) {
|
||||||
|
groupadd haze
|
||||||
|
useradd -u $HAZE_UID -g $HAZE_GID -G haze haze
|
||||||
|
} else {
|
||||||
|
groupadd -g $HAZE_GID haze
|
||||||
|
useradd -u $HAZE_UID -g $HAZE_GID haze
|
||||||
|
}
|
||||||
|
chown -R $"haze:($HAZE_GID)" /home/haze
|
||||||
|
ls -af /etc/home | each {|file| ln -s $file.name $"/home/haze/($file.name | path basename)" }
|
||||||
|
|
||||||
|
if ("/var/run/docker.sock" | path exists) {
|
||||||
|
let dockerGid = stat --format "%g" /var/run/docker.sock
|
||||||
|
groupadd docker -g $dockerGid
|
||||||
|
usermod -a -G docker haze
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("REDIS_TLS" in $env) {
|
||||||
|
cp /etc/supervisor/redis-tls.conf /etc/supervisor/enabled/
|
||||||
|
} else {
|
||||||
|
cp /etc/supervisor/redis-plain.conf /etc/supervisor/enabled/
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("BLACKFIRE_SERVER_ID" in $env) {
|
||||||
|
blackfire agent:config --server-id $env.BLACKFIRE_SERVER_ID --server-token $env.BLACKFIRE_SERVER_TOKEN
|
||||||
|
cp /etc/supervisor/blackfire.conf /etc/supervisor/enabled/
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("PROXY_BASE" in $env) {
|
||||||
|
let UPSTREAM_DNS = cat /etc/resolv.conf | grep nameserver | cut -d' ' -f 2
|
||||||
|
let RC = sed '/nameserver/d' /etc/resolv.conf
|
||||||
|
echo $RC | save -f /etc/resolv.conf
|
||||||
|
|
||||||
|
echo "\nnameserver 127.0.0.22\n" | save -a /etc/resolv.conf
|
||||||
|
|
||||||
|
echo $"s/UPSTREAM_DNS/($UPSTREAM_DNS)"
|
||||||
|
sed -i $"s/UPSTREAM_DNS/($UPSTREAM_DNS)/" /etc/dnsmasq.conf
|
||||||
|
echo $"s/PROXY_BASE/($env.PROXY_BASE)"
|
||||||
|
sed -i $"s/PROXY_BASE/($env.PROXY_BASE)/" /etc/dnsmasq.conf
|
||||||
|
echo $"s/HOST_IP/($env.HOST_IP)"
|
||||||
|
sed -i $"s/HOST_IP/($env.HOST_IP)/" /etc/dnsmasq.conf
|
||||||
|
|
||||||
|
cp /etc/supervisor/dnsmasq.conf /etc/supervisor/enabled/
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("FRANKENPHP" in $env) {
|
||||||
|
cp /etc/supervisor/frankenphp.conf /etc/supervisor/enabled/
|
||||||
|
} else {
|
||||||
|
cp /etc/supervisor/php-fpm.conf /etc/supervisor/enabled/
|
||||||
|
cp /etc/supervisor/nginx.conf /etc/supervisor/enabled/
|
||||||
|
}
|
||||||
|
|
||||||
|
exec supervisord -c /etc/supervisor/supervisord.conf
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
touch /var/log/nginx/access.log
|
|
||||||
touch /var/log/nginx/error.log
|
|
||||||
touch /var/log/cron/owncloud.log
|
|
||||||
|
|
||||||
mkdir -p /config
|
|
||||||
echo "# Options in here overwrite the builtin php.ini" > /config/php.ini
|
|
||||||
echo "# xdebug.mode = debug" >> /config/php.ini
|
|
||||||
echo "# xdebug.start_with_request = yes" >> /config/php.ini
|
|
||||||
chmod 0777 /config/php.ini
|
|
||||||
PHP_INI_DIR="$(php --ini | grep 'Scan' | cut -d ' ' -f7 | tr -d '"')"
|
|
||||||
ln -s /config/php.ini "$PHP_INI_DIR/zz_extra.ini"
|
|
||||||
|
|
||||||
HAZE_UID=${HAZE_UID:-www-data}
|
|
||||||
HAZE_GID=${HAZE_GID:-www-data}
|
|
||||||
|
|
||||||
nc-auto-config
|
|
||||||
shadow-setup
|
|
||||||
|
|
||||||
echo "Running as $HAZE_UID:$HAZE_GID"
|
|
||||||
|
|
||||||
mkdir -p /var/www/html/core/skeleton /var/www/html/build/integration/vendor /var/www/html/build/integration/output /var/www/html/build/integration/work /var/www/html/core/skeleton /var/www/.composer/cache /var/www/html/apps/spreed/tests/integration/vendor/composer
|
|
||||||
chown -R "$HAZE_UID":"$HAZE_GID" /var/www/html/data /var/www/html/config
|
|
||||||
chown "$HAZE_UID":"$HAZE_GID" /var/www/html/core/skeleton /var/www/html/build/integration/vendor /var/www/html/build/integration/composer.lock /var/www/html/build/integration/output /var/www/html/build/integration/work /var/www/html/core/skeleton /var/www/.composer/cache /var/www/html/apps/spreed/tests/integration/vendor/composer
|
|
||||||
|
|
||||||
echo "{}" > /var/www/html/build/integration/composer.lock
|
|
||||||
|
|
||||||
echo "Starting server using $SQL database…"
|
|
||||||
|
|
||||||
# tail --follow --retry /var/log/nginx/*.log /var/log/cron/owncloud.log &
|
|
||||||
|
|
||||||
chmod +sx /sbin/sudo
|
|
||||||
|
|
||||||
mkdir -p /var/log/nginx /tmp /var/run/blackfire
|
|
||||||
touch /var/log/nginx/access.log
|
|
||||||
touch /var/log/nginx/error.log
|
|
||||||
|
|
||||||
HAZE_UID=${HAZE_UID:-1000}
|
|
||||||
HAZE_GID=${HAZE_GID:-1000}
|
|
||||||
|
|
||||||
if [ "$(getent group "$HAZE_GID")" ]; then
|
|
||||||
groupadd haze
|
|
||||||
EXTRA_GROUP=" -G haze"
|
|
||||||
else
|
|
||||||
groupadd -g "$HAZE_GID" haze
|
|
||||||
EXTRA_GROUP=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
useradd -u "$HAZE_UID" -g "$HAZE_GID""$EXTRA_GROUP" haze
|
|
||||||
chown -R haze:"$HAZE_GID" /home/haze
|
|
||||||
|
|
||||||
if [ -f "/var/run/docker.sock" ]; then
|
|
||||||
groupadd docker -g "$(stat --format "%g" /var/run/docker.sock)"
|
|
||||||
usermod -a -G docker haze
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${REDIS_TLS:-}" ]
|
|
||||||
then
|
|
||||||
redis-server --protected-mode no \
|
|
||||||
--tls-port 6379 --port 0 \
|
|
||||||
--tls-cert-file /certificates/redis/server.crt \
|
|
||||||
--tls-key-file /certificates/redis/server.key \
|
|
||||||
--tls-ca-cert-file /certificates/redis/ca.crt &
|
|
||||||
else
|
|
||||||
redis-server --protected-mode no &
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${BLACKFIRE_SERVER_ID:-}" ]
|
|
||||||
then
|
|
||||||
sh -c '
|
|
||||||
yes | blackfire agent:config --server-id=$BLACKFIRE_SERVER_ID --server-token=$BLACKFIRE_SERVER_TOKEN
|
|
||||||
BLACKFIRE_LOG_LEVEL=4 BLACKFIRE_LOG_FILE=/var/log/agent.log blackfire agent &
|
|
||||||
'&
|
|
||||||
fi
|
|
||||||
|
|
||||||
php-fpm --fpm-config /etc/php-fpm.conf&
|
|
||||||
|
|
||||||
nginx -c /etc/nginx.conf
|
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
{runCommand}:
|
{runCommand}:
|
||||||
runCommand "configs" {} ''
|
runCommand "configs" {} ''
|
||||||
mkdir -p $out/etc
|
mkdir -p $out
|
||||||
mkdir -p $out/etc/sudoers.d
|
cp -r ${./configs} $out/etc
|
||||||
mkdir -p $out/conf
|
chmod -R +w $out/etc
|
||||||
cp ${./configs/cron.conf} $out/etc/oc-cron.conf
|
mkdir $out/etc/supervisor/enabled/
|
||||||
cp ${./configs/nginx-app.conf} $out/conf/nginx-app.conf
|
|
||||||
cp ${./configs/sudoers} $out/etc/sudoers.d/haze
|
|
||||||
cp -r ${./configs/nc} $out/etc/nc
|
|
||||||
cp ${./php-fpm.conf} $out/etc/php-fpm.conf
|
|
||||||
cp ${./nginx.conf} $out/etc/nginx.conf
|
|
||||||
''
|
''
|
||||||
|
|
|
||||||
6
nix/image/configs/dnsmasq.conf
Normal file
6
nix/image/configs/dnsmasq.conf
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
listen-address=127.0.0.22
|
||||||
|
no-resolv
|
||||||
|
|
||||||
|
address=/PROXY_BASE/HOST_IP
|
||||||
|
|
||||||
|
server=UPSTREAM_DNS
|
||||||
1
nix/image/configs/home/.sqliterc
Normal file
1
nix/image/configs/home/.sqliterc
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
.mode table
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
'redis' => ['host' => 'localhost'],
|
'redis' => ['host' => 'localhost'],
|
||||||
//PLACEHOLDER
|
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,3 @@
|
||||||
'verify_peer_name' => false,
|
'verify_peer_name' => false,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
//PLACEHOLDER
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ http {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
include /conf/nginx-app.conf;
|
include /etc/nginx-app.conf;
|
||||||
|
|
||||||
location ~ \.php(?:$|/) {
|
location ~ \.php(?:$|/) {
|
||||||
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
|
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
|
||||||
|
|
@ -109,5 +109,16 @@ http {
|
||||||
expires 7d; # Cache-Control policy borrowed from `.htaccess`
|
expires 7d; # Cache-Control policy borrowed from `.htaccess`
|
||||||
access_log off; # Optional: Don't log access to assets
|
access_log off; # Optional: Don't log access to assets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /fpm-status {
|
||||||
|
include /conf/fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
fastcgi_pass php-handler;
|
||||||
|
fastcgi_read_timeout 3600;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
fastcgi_request_buffering off;
|
||||||
|
fastcgi_buffering off;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
[global]
|
[global]
|
||||||
|
|
||||||
error_log = /proc/self/fd/2
|
error_log = /var/log/php-fpm-error.log
|
||||||
daemonize = no
|
daemonize = no
|
||||||
|
|
||||||
[www]
|
[www]
|
||||||
|
|
||||||
access.log = /proc/self/fd/2
|
access.log =/var/log/php-fpm-access.log
|
||||||
|
|
||||||
user = haze
|
user = haze
|
||||||
group = haze
|
group = haze
|
||||||
|
|
@ -21,6 +21,7 @@ pm.max_children = 5
|
||||||
pm.start_servers = 2
|
pm.start_servers = 2
|
||||||
pm.min_spare_servers = 1
|
pm.min_spare_servers = 1
|
||||||
pm.max_spare_servers = 3
|
pm.max_spare_servers = 3
|
||||||
|
pm.status_path = /fpm-status
|
||||||
|
|
||||||
clear_env = no
|
clear_env = no
|
||||||
|
|
||||||
2
nix/image/configs/supervisor/blackfire.conf
Normal file
2
nix/image/configs/supervisor/blackfire.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[program:blackfire]
|
||||||
|
command = blackfire agent
|
||||||
2
nix/image/configs/supervisor/dnsmasq.conf
Normal file
2
nix/image/configs/supervisor/dnsmasq.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[program:dnsmasq]
|
||||||
|
command = /bin/dnsmasq --keep-in-foreground -u root
|
||||||
3
nix/image/configs/supervisor/frankenphp.conf
Normal file
3
nix/image/configs/supervisor/frankenphp.conf
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[program:frankenphp]
|
||||||
|
command = /bin/frankenphp php-server
|
||||||
|
directory = /var/www/html
|
||||||
2
nix/image/configs/supervisor/nginx.conf
Normal file
2
nix/image/configs/supervisor/nginx.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[program:nginx]
|
||||||
|
command = /bin/nginx -c /etc/nginx.conf
|
||||||
2
nix/image/configs/supervisor/php-fpm.conf
Normal file
2
nix/image/configs/supervisor/php-fpm.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[program:php-fpm]
|
||||||
|
command = /bin/php-fpm --fpm-config /etc/php-fpm.conf
|
||||||
2
nix/image/configs/supervisor/redis-plain.conf
Normal file
2
nix/image/configs/supervisor/redis-plain.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[program:redis]
|
||||||
|
command = /bin/redis-server --protected-mode no
|
||||||
2
nix/image/configs/supervisor/redis-tls.conf
Normal file
2
nix/image/configs/supervisor/redis-tls.conf
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[program:redis-tls]
|
||||||
|
command = /bin/redis-server --protected-mode no --tls-port 6379 --port 0 --tls-cert-file /certificates/redis/server.crt --tls-key-file /certificates/redis/server.key --tls-ca-cert-file /certificates/redis/ca.crt
|
||||||
19
nix/image/configs/supervisor/supervisord.conf
Normal file
19
nix/image/configs/supervisor/supervisord.conf
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
[supervisord]
|
||||||
|
logfile = /dev/stdout
|
||||||
|
logfile_maxbytes = 0
|
||||||
|
nodaemon = true
|
||||||
|
pidfile = /var/run/supervisord.pid
|
||||||
|
user = root
|
||||||
|
|
||||||
|
[unix_http_server]
|
||||||
|
file = /var/run/supervisor.sock
|
||||||
|
chmod = 0777
|
||||||
|
|
||||||
|
[rpcinterface:supervisor]
|
||||||
|
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||||||
|
|
||||||
|
[supervisorctl]
|
||||||
|
serverurl = unix:///var/run/supervisor.sock
|
||||||
|
|
||||||
|
[include]
|
||||||
|
files = enabled/*
|
||||||
|
|
@ -7,10 +7,9 @@
|
||||||
blackfire,
|
blackfire,
|
||||||
coreutils,
|
coreutils,
|
||||||
getent,
|
getent,
|
||||||
|
writers,
|
||||||
shadow,
|
shadow,
|
||||||
buildEnv,
|
|
||||||
runCommand,
|
runCommand,
|
||||||
cacert,
|
|
||||||
callPackage,
|
callPackage,
|
||||||
cronie,
|
cronie,
|
||||||
redis,
|
redis,
|
||||||
|
|
@ -33,18 +32,20 @@
|
||||||
writeShellApplication,
|
writeShellApplication,
|
||||||
vim,
|
vim,
|
||||||
helix,
|
helix,
|
||||||
|
python3Packages,
|
||||||
|
dnsmasq,
|
||||||
|
frankenphp,
|
||||||
|
nushell,
|
||||||
}: let
|
}: let
|
||||||
inherit (builtins) toString;
|
inherit (builtins) toString compareVersions;
|
||||||
inherit (lib) readFile getExe concatStringsSep splitString take;
|
inherit (lib) readFile getExe concatStringsSep splitString take optionals;
|
||||||
|
|
||||||
|
version = (fromTOML (readFile ../../Cargo.toml)).package.version;
|
||||||
|
|
||||||
phpVersion = concatStringsSep "." (take 2 (splitString "." php.version));
|
phpVersion = concatStringsSep "." (take 2 (splitString "." php.version));
|
||||||
phpEnv = callPackage ./php.nix {inherit debug php;};
|
phpEnv = callPackage ./php.nix {inherit debug php;};
|
||||||
|
|
||||||
bootstrap = writeShellApplication {
|
bootstrap = writers.writeNuBin "bootstrap" (readFile ./bootstrap);
|
||||||
name = "bootstrap";
|
|
||||||
runtimeInputs = [getent];
|
|
||||||
text = readFile ./bootstrap.sh;
|
|
||||||
};
|
|
||||||
shadowSetupScript = writeShellApplication {
|
shadowSetupScript = writeShellApplication {
|
||||||
name = "shadow-setup";
|
name = "shadow-setup";
|
||||||
text = dockerTools.shadowSetup;
|
text = dockerTools.shadowSetup;
|
||||||
|
|
@ -70,14 +71,6 @@
|
||||||
php = phpEnv;
|
php = phpEnv;
|
||||||
};
|
};
|
||||||
|
|
||||||
phpunitWrapped = majorVersion:
|
|
||||||
writeShellApplication {
|
|
||||||
name = "phpunit${toString majorVersion}";
|
|
||||||
text = ''
|
|
||||||
${phpunitUnwrapped (toString majorVersion)}/bin/phpunit "$@"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
phpunit = writeShellApplication {
|
phpunit = writeShellApplication {
|
||||||
name = "phpunit";
|
name = "phpunit";
|
||||||
runtimeInputs = [jq];
|
runtimeInputs = [jq];
|
||||||
|
|
@ -145,6 +138,10 @@
|
||||||
oracle-instantclient
|
oracle-instantclient
|
||||||
vim
|
vim
|
||||||
helix
|
helix
|
||||||
|
python3Packages.supervisor
|
||||||
|
dnsmasq
|
||||||
|
nushell
|
||||||
|
getent
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -153,10 +150,19 @@
|
||||||
tag = phpVersion;
|
tag = phpVersion;
|
||||||
fromImage = baseImage;
|
fromImage = baseImage;
|
||||||
|
|
||||||
copyToRoot = [
|
copyToRoot =
|
||||||
|
[
|
||||||
phpEnv
|
phpEnv
|
||||||
phpEnv.packages.composer
|
phpEnv.packages.composer
|
||||||
phpunit
|
phpunit
|
||||||
|
]
|
||||||
|
++ optionals ((compareVersions phpVersion "8.2") == 1) [
|
||||||
|
(frankenphp.override {
|
||||||
|
php = php.withExtensions (import ./php-ext.nix {
|
||||||
|
inherit lib php;
|
||||||
|
enableBlackfire = false;
|
||||||
|
});
|
||||||
|
})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
|
@ -185,7 +191,14 @@ in
|
||||||
'';
|
'';
|
||||||
config = {
|
config = {
|
||||||
Cmd = [(getExe bootstrap)];
|
Cmd = [(getExe bootstrap)];
|
||||||
Env = ["EDITOR=hx" "WEBROOT=/var/www/html"];
|
Env = [
|
||||||
|
"EDITOR=hx"
|
||||||
|
"WEBROOT=/var/www/html"
|
||||||
|
"HAZE_IMAGE_VERSION=${toString version}"
|
||||||
|
];
|
||||||
WorkingDir = "/var/www/html";
|
WorkingDir = "/var/www/html";
|
||||||
|
Labels = {
|
||||||
|
"nl.icewind.haze.version" = toString version;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
45
nix/image/php-ext.nix
Normal file
45
nix/image/php-ext.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
php,
|
||||||
|
debug ? false,
|
||||||
|
enableBlackfire ? true,
|
||||||
|
}: let
|
||||||
|
inherit (builtins) compareVersions;
|
||||||
|
inherit (lib) optionals;
|
||||||
|
withBlackfire = enableBlackfire && !debug && ((compareVersions php.version "8.1.0") == 1);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
enabled,
|
||||||
|
all,
|
||||||
|
}:
|
||||||
|
enabled
|
||||||
|
++ (with all;
|
||||||
|
[
|
||||||
|
xdebug
|
||||||
|
excimer
|
||||||
|
inotify
|
||||||
|
redis
|
||||||
|
oci8
|
||||||
|
zip
|
||||||
|
pdo
|
||||||
|
pdo_pgsql
|
||||||
|
pdo_sqlite
|
||||||
|
pdo_mysql
|
||||||
|
pgsql
|
||||||
|
intl
|
||||||
|
curl
|
||||||
|
mbstring
|
||||||
|
pcntl
|
||||||
|
ldap
|
||||||
|
exif
|
||||||
|
gmp
|
||||||
|
apcu
|
||||||
|
ffi
|
||||||
|
imagick
|
||||||
|
]
|
||||||
|
++ optionals (!debug) [
|
||||||
|
# smbclient # this breaks the build for no apparent reason
|
||||||
|
]
|
||||||
|
++ optionals withBlackfire [
|
||||||
|
blackfire
|
||||||
|
])
|
||||||
|
|
@ -2,46 +2,9 @@
|
||||||
lib,
|
lib,
|
||||||
php,
|
php,
|
||||||
debug ? false,
|
debug ? false,
|
||||||
}: let
|
}:
|
||||||
inherit (builtins) compareVersions;
|
php.buildEnv {
|
||||||
inherit (lib) optionals;
|
extensions = import ./php-ext.nix {inherit lib php debug;};
|
||||||
withBlackfire = !debug && ((compareVersions php.version "8.1.0") == 1);
|
|
||||||
in
|
|
||||||
php.buildEnv {
|
|
||||||
extensions = {
|
|
||||||
enabled,
|
|
||||||
all,
|
|
||||||
}:
|
|
||||||
enabled
|
|
||||||
++ (with all;
|
|
||||||
[
|
|
||||||
xdebug
|
|
||||||
excimer
|
|
||||||
inotify
|
|
||||||
redis
|
|
||||||
oci8
|
|
||||||
zip
|
|
||||||
pdo
|
|
||||||
pdo_pgsql
|
|
||||||
pdo_sqlite
|
|
||||||
pdo_mysql
|
|
||||||
pgsql
|
|
||||||
intl
|
|
||||||
curl
|
|
||||||
mbstring
|
|
||||||
pcntl
|
|
||||||
ldap
|
|
||||||
exif
|
|
||||||
gmp
|
|
||||||
apcu
|
|
||||||
ffi
|
|
||||||
]
|
|
||||||
++ optionals (!debug) [
|
|
||||||
smbclient # this breaks the build for no apparent reason
|
|
||||||
]
|
|
||||||
++ optionals withBlackfire [
|
|
||||||
blackfire
|
|
||||||
]);
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
xdebug.mode=debug,trace,profile
|
xdebug.mode=debug,trace,profile
|
||||||
xdebug.start_with_request=trigger
|
xdebug.start_with_request=trigger
|
||||||
|
|
@ -58,4 +21,4 @@ in
|
||||||
apc.enable_cli=1
|
apc.enable_cli=1
|
||||||
opcache.enable_cli=1
|
opcache.enable_cli=1
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,22 @@
|
||||||
#!/bin/sh
|
#!/bin/nu
|
||||||
|
|
||||||
USER=$1
|
def main [username: string, password: string] {
|
||||||
PASSWORD=$2
|
cd $env.WEBROOT;
|
||||||
|
let sql = match $env.SQL {
|
||||||
|
"oracle" => "oci"
|
||||||
|
"mariadb" => "mysql"
|
||||||
|
_ => $env.SQL
|
||||||
|
}
|
||||||
|
let dbName = match $env.SQL {
|
||||||
|
"oracle" => "xe"
|
||||||
|
_ => "haze"
|
||||||
|
}
|
||||||
|
let dbUser = match $env.SQL {
|
||||||
|
"oracle" => "system"
|
||||||
|
_ => "haze"
|
||||||
|
}
|
||||||
|
let dbPass = "haze"
|
||||||
|
let dbHost = $env.SQL
|
||||||
|
|
||||||
if [ -z "$USER" ] || [ -z "$PASSWORD" ]; then
|
occ maintenance:install --admin-user $username --admin-pass $password --database $sql --database-name $dbName --database-host $dbHost --database-user $dbUser --database-pass $dbPass
|
||||||
echo "Usage: install \$USER \$PASSWORD"
|
}
|
||||||
exit;
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd $WEBROOT
|
|
||||||
|
|
||||||
if [ "$SQL" = "oracle" ]; then
|
|
||||||
# oracle is a special snowflake
|
|
||||||
occ maintenance:install --admin-user=$USER --admin-pass=$PASSWORD --database=oci --database-name=xe --database-host=$SQL --database-user=system --database-pass=haze
|
|
||||||
elif [ "$SQL" = "mariadb" ]; then
|
|
||||||
occ maintenance:install --admin-user=$USER --admin-pass=$PASSWORD --database=mysql --database-name=haze --database-host=$SQL --database-user=haze --database-pass=haze
|
|
||||||
else
|
|
||||||
occ maintenance:install --admin-user=$USER --admin-pass=$PASSWORD --database=$SQL --database-name=haze --database-host=$SQL --database-user=haze --database-pass=haze
|
|
||||||
fi;
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,22 @@
|
||||||
#!/bin/sh
|
#!/bin/nu
|
||||||
|
|
||||||
cd $WEBROOT/build/integration
|
def --wrapped main [feature: path, ...rest] {
|
||||||
./run.sh "$@"
|
mut feature = $feature;
|
||||||
|
mut workdir = $"($env.WEBROOT)/build/integration"
|
||||||
|
if ($feature | str starts-with "apps/") {
|
||||||
|
let parts = $feature | split row '/'
|
||||||
|
occ app:enable $parts.1
|
||||||
|
let parts = $feature | split row -n 2 '/features/'
|
||||||
|
$workdir = $parts.0
|
||||||
|
$feature = $"features/($parts.1)"
|
||||||
|
} else if ($feature | str starts-with "build/integration/") {
|
||||||
|
$feature = $feature | str replace "build/integration/" ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# don't use the proxy urls for generated urls
|
||||||
|
occ config:system:delete overwritehost
|
||||||
|
occ config:system:delete overwriteprotocol
|
||||||
|
|
||||||
|
cd $workdir
|
||||||
|
bash run.sh $feature ...$rest
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/nu
|
||||||
|
|
||||||
touch /var/log/nginx/access.log
|
touch /var/log/nginx/access.log
|
||||||
touch /var/log/nginx/error.log
|
touch /var/log/nginx/error.log
|
||||||
|
|
@ -7,64 +7,30 @@ touch /var/log/cron/owncloud.log
|
||||||
cp /etc/nc/config.php /var/www/html/config/config.php
|
cp /etc/nc/config.php /var/www/html/config/config.php
|
||||||
chmod 0755 /var/www/html/config/config.php
|
chmod 0755 /var/www/html/config/config.php
|
||||||
|
|
||||||
if [ "$SQL" = "mysql" ]
|
let configName = match $env.SQL {
|
||||||
then
|
"oracle" => "oci"
|
||||||
cp /etc/nc/autoconfig_mysql.php /var/www/html/config/autoconfig.php
|
_ => $env.SQL
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$SQL" = "mariadb" ]
|
}
|
||||||
then
|
let configPath = $"/etc/nc/autoconfig_($configName).php"
|
||||||
cp /etc/nc/autoconfig_mariadb.php /var/www/html/config/autoconfig.php
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$SQL" = "pgsql" ]
|
if ($configPath | path exists) {
|
||||||
then
|
cp $configPath /var/www/html/config/autoconfig.php
|
||||||
cp /etc/nc/autoconfig_pgsql.php /var/www/html/config/autoconfig.php
|
}
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$SQL" = "oci" ]
|
def loadExtraConfig [name: string] {
|
||||||
then
|
sed -i $'/\/\/PLACEHOLDER/ r /etc/nc/($name).php' /var/www/html/config/config.php
|
||||||
cp /etc/nc/autoconfig_oci.php /var/www/html/config/autoconfig.php
|
}
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${S3:-}" ]
|
let extraConfigs = ["S3", "S3S", "S3MB", "S3M", "SWIFT", "SWIFTV3", "AZURE"];
|
||||||
then
|
$extraConfigs | each {
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/s3.php' /var/www/html/config/config.php
|
if ($in in $env) {
|
||||||
fi
|
loadExtraConfig ($in | str downcase)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if [ -n "${S3S:-}" ]
|
if ("REDIS_TLS" in $env) {
|
||||||
then
|
loadExtraConfig "redis-tls"
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/s3s.php' /var/www/html/config/config.php
|
} else {
|
||||||
fi
|
loadExtraConfig "redis-default"
|
||||||
|
}
|
||||||
if [ -n "${S3MB:-}" ]
|
|
||||||
then
|
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/s3mb.php' /var/www/html/config/config.php
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${S3M:-}" ]
|
|
||||||
then
|
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/s3m.php' /var/www/html/config/config.php
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${SWIFT:-}" ]
|
|
||||||
then
|
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/swift.php' /var/www/html/config/config.php
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${SWIFTV3:-}" ]
|
|
||||||
then
|
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/swiftv3.php' /var/www/html/config/config.php
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${AZURE:-}" ]
|
|
||||||
then
|
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/azure.php' /var/www/html/config/config.php
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "${REDIS_TLS:-}" ]
|
|
||||||
then
|
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/redis-tls.php' /var/www/html/config/config.php
|
|
||||||
else
|
|
||||||
sed -i '/\/\/PLACEHOLDER/ r /etc/nc/redis-default.php' /var/www/html/config/config.php
|
|
||||||
fi
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/sh
|
#!/bin/nu
|
||||||
|
|
||||||
export XDEBUG_SESSION=haze
|
def --wrapped main [...rest] {
|
||||||
|
XDEBUG_SESSION=haze php $"($env.WEBROOT)/occ" ...$rest
|
||||||
php $WEBROOT/occ "$@"
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/nu
|
||||||
|
|
||||||
cd $WEBROOT
|
def --wrapped main [...rest] {
|
||||||
|
cd $env.WEBROOT
|
||||||
|
|
||||||
export XDEBUG_SESSION=haze
|
XDEBUG_SESSION=haze phpunit --configuration $"($env.WEBROOT)/tests/phpunit-autotest.xml" ...$rest
|
||||||
|
}
|
||||||
phpunit --configuration $WEBROOT/tests/phpunit-autotest.xml $@
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
rustPlatform,
|
rustPlatform,
|
||||||
pkg-config,
|
|
||||||
lib,
|
lib,
|
||||||
git,
|
git,
|
||||||
}: let
|
}: let
|
||||||
|
|
@ -10,7 +9,7 @@
|
||||||
src = sourceByRegex ../. ["Cargo.*" "(src|certificates)(/.*)?"];
|
src = sourceByRegex ../. ["Cargo.*" "(src|certificates)(/.*)?"];
|
||||||
version = (fromTOML (readFile ../Cargo.toml)).package.version;
|
version = (fromTOML (readFile ../Cargo.toml)).package.version;
|
||||||
in
|
in
|
||||||
rustPlatform.buildRustPackage rec {
|
rustPlatform.buildRustPackage {
|
||||||
pname = "haze";
|
pname = "haze";
|
||||||
|
|
||||||
inherit src version;
|
inherit src version;
|
||||||
|
|
@ -20,7 +19,7 @@ in
|
||||||
cargoLock = {
|
cargoLock = {
|
||||||
lockFile = ../Cargo.lock;
|
lockFile = ../Cargo.lock;
|
||||||
outputHashes = {
|
outputHashes = {
|
||||||
"hyper-reverse-proxy-0.5.2-dev" = "sha256-+ebi4FVVkiOpf75e8K5oGkHJBYQjLNJhUPNj+78zd7Q=";
|
"hyper-reverse-proxy-0.5.2-dev" = "sha256-awmj5aLFTea+kj81cwmfP1HWlWezwEKfyQSUJWjtamk=";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ impl LogService {
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum ExecService {
|
pub enum ExecService {
|
||||||
Db,
|
Db,
|
||||||
|
Service(Service),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HazeArgs {
|
impl HazeArgs {
|
||||||
|
|
@ -232,6 +233,14 @@ impl HazeArgs {
|
||||||
args.next();
|
args.next();
|
||||||
Some(ExecService::Db)
|
Some(ExecService::Db)
|
||||||
}
|
}
|
||||||
|
Some(arg) => Service::from_type(&[], arg.as_ref())
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|services| services.into_iter().next())
|
||||||
|
.next()
|
||||||
|
.map(|service| {
|
||||||
|
args.next();
|
||||||
|
ExecService::Service(service)
|
||||||
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,14 +219,6 @@ impl Database {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
cmd: if self.image() == "mysql:8" {
|
|
||||||
Some(vec![
|
|
||||||
"--default-authentication-plugin".into(),
|
|
||||||
"mysql_native_password".into(),
|
|
||||||
])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let id = docker
|
let id = docker
|
||||||
|
|
|
||||||
66
src/git.rs
66
src/git.rs
|
|
@ -2,11 +2,15 @@ use crate::config::HazeConfig;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use git2::build::CheckoutBuilder;
|
use git2::build::CheckoutBuilder;
|
||||||
use git2::{Branch, BranchType, Repository, RepositoryState};
|
use git2::{Branch, BranchType, Repository, RepositoryState};
|
||||||
|
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
|
||||||
use miette::{Context, IntoDiagnostic};
|
use miette::{Context, IntoDiagnostic};
|
||||||
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
|
use rayon::ThreadPoolBuilder;
|
||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
fn find_app_repos(config: &HazeConfig) -> Result<impl Iterator<Item = PathBuf>> {
|
fn find_app_repos(config: &HazeConfig) -> Result<impl Iterator<Item = PathBuf>> {
|
||||||
let apps_dirs = once(config.sources_root.as_path().join("apps"))
|
let apps_dirs = once(config.sources_root.as_path().join("apps"))
|
||||||
|
|
@ -83,38 +87,66 @@ const GIT_BINARY: &str = match option_env!("GIT_BINARY") {
|
||||||
pub fn pull_all(config: &HazeConfig) -> Result<()> {
|
pub fn pull_all(config: &HazeConfig) -> Result<()> {
|
||||||
let (max_app, max_branch) = longest_app_branch(config)?;
|
let (max_app, max_branch) = longest_app_branch(config)?;
|
||||||
|
|
||||||
for app_dir in find_app_repos(config)? {
|
let progress = MultiProgress::new();
|
||||||
|
let pull_style = ProgressStyle::with_template("{spinner:.green} {msg}").unwrap();
|
||||||
|
|
||||||
|
let pool = ThreadPoolBuilder::new()
|
||||||
|
.num_threads(8)
|
||||||
|
.build()
|
||||||
|
.into_diagnostic()?;
|
||||||
|
let repos = find_app_repos(config)?.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
pool.install(|| {
|
||||||
|
repos.par_iter().for_each(|app_dir| {
|
||||||
let app_name = app_dir.file_name().unwrap().to_string_lossy();
|
let app_name = app_dir.file_name().unwrap().to_string_lossy();
|
||||||
let repo = Repository::init(&app_dir)
|
let Ok(repo) = Repository::init(app_dir) else {
|
||||||
.into_diagnostic()
|
return;
|
||||||
.wrap_err_with(|| format!("Failed to open repository {}", app_dir.display()))?;
|
};
|
||||||
let branch_name = current_branch_name(&repo).unwrap_or("unknown".into());
|
let branch_name = current_branch_name(&repo).unwrap_or("unknown".into());
|
||||||
|
|
||||||
print!(
|
let bar = ProgressBar::new_spinner().with_style(pull_style.clone());
|
||||||
"{app_name:<app_width$} - {branch_name:<branch_width$}",
|
bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
|
let bar = progress.add(bar);
|
||||||
|
|
||||||
|
let msg = |state: &str| {
|
||||||
|
format!(
|
||||||
|
"{app_name:<app_width$} - {branch_name:<branch_width$}{state}",
|
||||||
app_width = max_app,
|
app_width = max_app,
|
||||||
branch_width = max_branch
|
branch_width = max_branch
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
if repo.state() != RepositoryState::Clean {
|
if repo.state() != RepositoryState::Clean {
|
||||||
println!(": repository not clean ❌");
|
bar.set_message(msg(" ⨯ repository not clean"));
|
||||||
continue;
|
bar.finish();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let output = Command::new(GIT_BINARY)
|
bar.set_message(msg(""));
|
||||||
|
|
||||||
|
let output = match Command::new(GIT_BINARY)
|
||||||
.arg("pull")
|
.arg("pull")
|
||||||
.current_dir(&app_dir)
|
.current_dir(app_dir)
|
||||||
.output()
|
.output()
|
||||||
.into_diagnostic()
|
{
|
||||||
.wrap_err_with(|| format!("Failed to run git pull for {}", app_dir.display()))?;
|
Ok(output) => output,
|
||||||
|
Err(error) => {
|
||||||
|
bar.set_message(msg(&format!(" ⨯ {error}")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if output.status.success() {
|
if output.status.success() {
|
||||||
println!(" ✓");
|
bar.set_message(msg(" ✓"));
|
||||||
} else {
|
} else {
|
||||||
println!(" ❌");
|
let err = String::from_utf8_lossy(&output.stderr);
|
||||||
eprintln!("{}", String::from_utf8_lossy(&output.stderr))
|
let err_line = err.lines().next().unwrap();
|
||||||
}
|
bar.set_message(msg(&format!(" ⨯ {err_line}")));
|
||||||
}
|
}
|
||||||
|
bar.finish();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
37
src/image.rs
37
src/image.rs
|
|
@ -5,11 +5,48 @@ use futures_util::StreamExt;
|
||||||
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
|
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
|
||||||
use miette::{IntoDiagnostic, Result, WrapErr};
|
use miette::{IntoDiagnostic, Result, WrapErr};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq)]
|
||||||
|
pub struct ImageVersion {
|
||||||
|
pub major: u8,
|
||||||
|
pub minor: u8,
|
||||||
|
pub patch: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ImageVersion {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||||
|
let mut parts = s.split('.');
|
||||||
|
let major = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||||
|
let minor = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||||
|
let patch = parts.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||||
|
Ok(ImageVersion {
|
||||||
|
major,
|
||||||
|
minor,
|
||||||
|
patch,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ImageVersion {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn image_exists(docker: &Docker, image: &str) -> bool {
|
pub async fn image_exists(docker: &Docker, image: &str) -> bool {
|
||||||
docker.inspect_image(image).await.is_ok()
|
docker.inspect_image(image).await.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn image_version(docker: &Docker, image: &str) -> Option<ImageVersion> {
|
||||||
|
let labels = docker.inspect_image(image).await.ok()?.config?.labels?;
|
||||||
|
let label = labels.get("nl.icewind.haze.version")?;
|
||||||
|
ImageVersion::from_str(label).ok()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn update_image(docker: &Docker, image: &str) -> Result<()> {
|
pub async fn update_image(docker: &Docker, image: &str) -> Result<()> {
|
||||||
if image_exists(docker, image).await {
|
if image_exists(docker, image).await {
|
||||||
force_pull_image(docker, image).await?;
|
force_pull_image(docker, image).await?;
|
||||||
|
|
|
||||||
56
src/main.rs
56
src/main.rs
|
|
@ -148,6 +148,9 @@ async fn main() -> Result<ExitCode> {
|
||||||
root,
|
root,
|
||||||
} => {
|
} => {
|
||||||
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
|
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
|
||||||
|
let env = get_forward_env();
|
||||||
|
let tty = atty::is(atty::Stream::Stdout);
|
||||||
|
|
||||||
match service {
|
match service {
|
||||||
None => {
|
None => {
|
||||||
let command = if command.is_empty() {
|
let command = if command.is_empty() {
|
||||||
|
|
@ -155,8 +158,7 @@ async fn main() -> Result<ExitCode> {
|
||||||
} else {
|
} else {
|
||||||
command
|
command
|
||||||
};
|
};
|
||||||
let env = get_forward_env();
|
|
||||||
let tty = atty::is(atty::Stream::Stdout);
|
|
||||||
let user = if root { "root" } else { "haze" };
|
let user = if root { "root" } else { "haze" };
|
||||||
if tty {
|
if tty {
|
||||||
exec_tty(&docker, &cloud.id, user, command, env).await?;
|
exec_tty(&docker, &cloud.id, user, command, env).await?;
|
||||||
|
|
@ -165,19 +167,42 @@ async fn main() -> Result<ExitCode> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ExecService::Db) => {
|
Some(ExecService::Db) => {
|
||||||
cloud
|
let command = if command.is_empty() {
|
||||||
.db()
|
|
||||||
.exec_sh(
|
|
||||||
&docker,
|
|
||||||
&cloud.id,
|
|
||||||
if command.is_empty() {
|
|
||||||
vec!["bash".to_string()]
|
vec!["bash".to_string()]
|
||||||
} else {
|
} else {
|
||||||
command
|
command
|
||||||
},
|
};
|
||||||
atty::is(atty::Stream::Stdout),
|
|
||||||
)
|
cloud.db().exec_sh(&docker, &cloud.id, command, tty).await?;
|
||||||
.await?;
|
}
|
||||||
|
Some(ExecService::Service(service)) => {
|
||||||
|
let Some(container) = service.container_name(&cloud.id) else {
|
||||||
|
eprintln!(
|
||||||
|
"Service {} can't be exec'ed as it has no associated container",
|
||||||
|
service.name()
|
||||||
|
);
|
||||||
|
return Ok(ExitCode::FAILURE);
|
||||||
|
};
|
||||||
|
if service.exec_shell() == "" && command.is_empty() {
|
||||||
|
eprintln!(
|
||||||
|
"Service {} can't be exec'ed as it has no shell",
|
||||||
|
service.name()
|
||||||
|
);
|
||||||
|
return Ok(ExitCode::FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
let command = if command.is_empty() {
|
||||||
|
vec![service.exec_shell().to_string()]
|
||||||
|
} else {
|
||||||
|
command
|
||||||
|
};
|
||||||
|
|
||||||
|
let user = if root { "root" } else { service.exec_user() };
|
||||||
|
if tty {
|
||||||
|
exec_tty(&docker, &container, user, command, env).await?;
|
||||||
|
} else {
|
||||||
|
exec(&docker, &container, user, command, env, Some(stdout())).await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -633,12 +658,7 @@ async fn setup(docker: &Docker, options: CloudOptions, config: &HazeConfig) -> R
|
||||||
for service in cloud.services() {
|
for service in cloud.services() {
|
||||||
for cmd in service.post_setup(docker, &cloud.id, config).await? {
|
for cmd in service.post_setup(docker, &cloud.id, config).await? {
|
||||||
cloud
|
cloud
|
||||||
.exec(
|
.exec(docker, cmd, false, Vec::<String>::default())
|
||||||
docker,
|
|
||||||
shell_words::split(&cmd).into_diagnostic()?,
|
|
||||||
false,
|
|
||||||
Vec::<String>::default(),
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/php.rs
19
src/php.rs
|
|
@ -1,6 +1,7 @@
|
||||||
|
use owo_colors::OwoColorize;
|
||||||
use crate::config::ProxyConfig;
|
use crate::config::ProxyConfig;
|
||||||
use crate::database::Database;
|
use crate::database::Database;
|
||||||
use crate::image::pull_image;
|
use crate::image::{image_version, pull_image, ImageVersion};
|
||||||
use crate::network::ensure_network_exists;
|
use crate::network::ensure_network_exists;
|
||||||
use crate::service::Service;
|
use crate::service::Service;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::ServiceTrait;
|
||||||
|
|
@ -123,6 +124,17 @@ impl PhpVersion {
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
ensure_network_exists(docker, "haze").await?;
|
ensure_network_exists(docker, "haze").await?;
|
||||||
pull_image(docker, self.image()).await?;
|
pull_image(docker, self.image()).await?;
|
||||||
|
|
||||||
|
let image_version = image_version(docker, self.image()).await;
|
||||||
|
let haze_version = ImageVersion::from_str(env!("CARGO_PKG_VERSION"));
|
||||||
|
if let (Some(image_version), Ok(haze_version)) = (image_version, haze_version) {
|
||||||
|
if image_version < haze_version {
|
||||||
|
eprintln!("{}: image version is out of date, run {} to update.", "Warning".red(), "haze update".blue());
|
||||||
|
eprintln!(" Haze version: {}", haze_version.bright_yellow());
|
||||||
|
eprintln!(" Image version: {}", image_version.bright_yellow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let options = Some(CreateContainerOptions {
|
let options = Some(CreateContainerOptions {
|
||||||
name: Some(id.to_string()),
|
name: Some(id.to_string()),
|
||||||
..CreateContainerOptions::default()
|
..CreateContainerOptions::default()
|
||||||
|
|
@ -148,6 +160,11 @@ impl PhpVersion {
|
||||||
proxy_config.addr(id, IpAddr::V4(Ipv4Addr::LOCALHOST))
|
proxy_config.addr(id, IpAddr::V4(Ipv4Addr::LOCALHOST))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
env.push(format!("HOST_IP={host}"));
|
||||||
|
if !proxy_config.address.is_empty() {
|
||||||
|
env.push(format!("PROXY_BASE={}", proxy_config.address));
|
||||||
|
}
|
||||||
|
|
||||||
let mut labels = hashmap! {
|
let mut labels = hashmap! {
|
||||||
"haze-type".to_string() => "cloud".to_string(),
|
"haze-type".to_string() => "cloud".to_string(),
|
||||||
"haze-db".to_string() => db.name().to_string(),
|
"haze-db".to_string() => db.name().to_string(),
|
||||||
|
|
|
||||||
72
src/proxy.rs
72
src/proxy.rs
|
|
@ -5,26 +5,34 @@ use axum::http::header::HOST;
|
||||||
use axum::http::HeaderValue;
|
use axum::http::HeaderValue;
|
||||||
use axum::{
|
use axum::{
|
||||||
body::Body,
|
body::Body,
|
||||||
extract::{Request, State},
|
extract::Request,
|
||||||
response::{IntoResponse, Response},
|
response::{IntoResponse, Response},
|
||||||
Router,
|
|
||||||
};
|
};
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
|
use futures_util::StreamExt;
|
||||||
|
use hyper::body::Incoming;
|
||||||
|
use hyper::server::conn::http1;
|
||||||
|
use hyper::service::service_fn;
|
||||||
use hyper::StatusCode;
|
use hyper::StatusCode;
|
||||||
|
use hyper_util::rt::TokioIo;
|
||||||
use hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor};
|
use hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor};
|
||||||
use miette::{miette, IntoDiagnostic};
|
use miette::{miette, IntoDiagnostic};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::convert::Infallible;
|
||||||
use std::fs::{create_dir_all, set_permissions};
|
use std::fs::{create_dir_all, set_permissions};
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::pin::pin;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use tokio::io::{AsyncRead, AsyncWrite};
|
||||||
use tokio::net::UnixListener;
|
use tokio::net::UnixListener;
|
||||||
use tokio::signal::ctrl_c;
|
use tokio::signal::ctrl_c;
|
||||||
use tokio::spawn;
|
use tokio::spawn;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
use tokio_stream::wrappers::{TcpListenerStream, UnixListenerStream};
|
||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
struct ActiveInstances {
|
struct ActiveInstances {
|
||||||
|
|
@ -163,20 +171,26 @@ async fn serve(instances: ActiveInstances, listen: String, base_address: String)
|
||||||
ctrl_c().await.ok();
|
ctrl_c().await.ok();
|
||||||
};
|
};
|
||||||
|
|
||||||
let app = Router::new().fallback(handler).with_state(AppState {
|
let state = AppState {
|
||||||
instances: instances.clone(),
|
instances: instances.clone(),
|
||||||
base_address: base_address.clone(),
|
base_address: base_address.clone(),
|
||||||
proxy_client: Arc::new(proxy_client),
|
proxy_client: Arc::new(proxy_client),
|
||||||
});
|
};
|
||||||
|
|
||||||
if !listen.starts_with('/') {
|
if !listen.starts_with('/') {
|
||||||
let addr: SocketAddr = listen.parse().into_diagnostic()?;
|
let addr: SocketAddr = listen.parse().into_diagnostic()?;
|
||||||
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
let listener = tokio::net::TcpListener::bind(addr).await.unwrap();
|
||||||
println!("listening on {}", listener.local_addr().unwrap());
|
println!("listening on {}", listener.local_addr().unwrap());
|
||||||
axum::serve(listener, app)
|
let mut connections = pin!(TcpListenerStream::new(listener).take_until(cancel));
|
||||||
.with_graceful_shutdown(cancel)
|
|
||||||
.await
|
while let Some(stream) = connections.next().await {
|
||||||
.unwrap();
|
match stream {
|
||||||
|
Ok(stream) => handle_connection(state.clone(), stream),
|
||||||
|
Err(error) => {
|
||||||
|
error!(%error, "connection failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let listen: PathBuf = listen.into();
|
let listen: PathBuf = listen.into();
|
||||||
if let Some(parent) = listen.parent() {
|
if let Some(parent) = listen.parent() {
|
||||||
|
|
@ -187,18 +201,42 @@ async fn serve(instances: ActiveInstances, listen: String, base_address: String)
|
||||||
}
|
}
|
||||||
let _ = tokio::fs::remove_file(&listen).await;
|
let _ = tokio::fs::remove_file(&listen).await;
|
||||||
|
|
||||||
let uds = UnixListener::bind(&listen).unwrap();
|
let listener = UnixListener::bind(&listen).unwrap();
|
||||||
|
println!("listening on {}", listen.display());
|
||||||
set_permissions(&listen, PermissionsExt::from_mode(0o666)).into_diagnostic()?;
|
set_permissions(&listen, PermissionsExt::from_mode(0o666)).into_diagnostic()?;
|
||||||
|
|
||||||
axum::serve(uds, app)
|
let mut connections = pin!(UnixListenerStream::new(listener).take_until(cancel));
|
||||||
.with_graceful_shutdown(cancel)
|
|
||||||
.await
|
while let Some(stream) = connections.next().await {
|
||||||
.unwrap();
|
match stream {
|
||||||
|
Ok(stream) => handle_connection(state.clone(), stream),
|
||||||
|
Err(error) => {
|
||||||
|
error!(%error, "connection failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_connection<I: AsyncRead + AsyncWrite + Unpin + Send + 'static>(
|
||||||
|
state: AppState,
|
||||||
|
stream: I,
|
||||||
|
) {
|
||||||
|
let io = TokioIo::new(stream);
|
||||||
|
// Spawn a tokio task to serve multiple connections concurrently
|
||||||
|
tokio::task::spawn(async move {
|
||||||
|
if let Err(err) = http1::Builder::new()
|
||||||
|
.serve_connection(io, service_fn(move |req| handler(state.clone(), req)))
|
||||||
|
.with_upgrades()
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
eprintln!("Error serving connection: {:?}", err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_remote(
|
async fn get_remote(
|
||||||
host: Option<&HeaderValue>,
|
host: Option<&HeaderValue>,
|
||||||
instances: &ActiveInstances,
|
instances: &ActiveInstances,
|
||||||
|
|
@ -232,9 +270,9 @@ async fn get_remote(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client = hyper_util::client::legacy::Client<HttpConnector, Body>;
|
type Client = hyper_util::client::legacy::Client<HttpConnector, Incoming>;
|
||||||
|
|
||||||
async fn handler(State(state): State<AppState>, mut req: Request) -> Result<Response, StatusCode> {
|
async fn handler(state: AppState, mut req: Request<Incoming>) -> Result<Response, Infallible> {
|
||||||
let host = req.headers().get(HOST).cloned();
|
let host = req.headers().get(HOST).cloned();
|
||||||
let remote = match get_remote(host.as_ref(), &state.instances, &state.base_address).await {
|
let remote = match get_remote(host.as_ref(), &state.instances, &state.base_address).await {
|
||||||
Ok(remote) => remote,
|
Ok(remote) => remote,
|
||||||
|
|
@ -259,13 +297,13 @@ async fn handler(State(state): State<AppState>, mut req: Request) -> Result<Resp
|
||||||
IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
&uri,
|
&uri,
|
||||||
req,
|
req,
|
||||||
&state.proxy_client,
|
state.proxy_client.as_ref(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(response) => Ok(response.map(Body::new)),
|
Ok(response) => Ok(response.map(Body::new)),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
error!(%error, "error while proxying request");
|
error!(?error, "error while proxying request");
|
||||||
Ok(StatusCode::BAD_REQUEST.into_response())
|
Ok(StatusCode::BAD_REQUEST.into_response())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ mod sftp;
|
||||||
mod redis;
|
mod redis;
|
||||||
mod sharded;
|
mod sharded;
|
||||||
mod smb;
|
mod smb;
|
||||||
|
mod webhook;
|
||||||
|
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::{HazeConfig, Preset, ProxyConfig};
|
use crate::config::{HazeConfig, Preset, ProxyConfig};
|
||||||
|
|
@ -29,9 +30,10 @@ pub use crate::service::office::Office;
|
||||||
pub use crate::service::onlyoffice::OnlyOffice;
|
pub use crate::service::onlyoffice::OnlyOffice;
|
||||||
pub use crate::service::push::NotifyPush;
|
pub use crate::service::push::NotifyPush;
|
||||||
use crate::service::redis::Redis;
|
use crate::service::redis::Redis;
|
||||||
use crate::service::sftp::Sftp;
|
use crate::service::sftp::{Sftp, SftpKey};
|
||||||
use crate::service::sharded::{Sharding, ShardingMigrate, ShardingMigrateUnset, SingleShard};
|
use crate::service::sharded::{Sharding, ShardingMigrate, ShardingMigrateUnset, SingleShard};
|
||||||
use crate::service::smb::Smb;
|
use crate::service::smb::Smb;
|
||||||
|
use crate::service::webhook::Webhook;
|
||||||
use bollard::models::ContainerState;
|
use bollard::models::ContainerState;
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
|
|
@ -114,7 +116,7 @@ pub trait ServiceTrait {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,6 +194,14 @@ pub trait ServiceTrait {
|
||||||
fn proxy_port(&self) -> u16 {
|
fn proxy_port(&self) -> u16 {
|
||||||
80
|
80
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exec_user(&self) -> &'static str {
|
||||||
|
"root"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_shell(&self) -> &'static str {
|
||||||
|
"bash"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
|
|
@ -207,6 +217,19 @@ impl ServiceTrait for RedisTls {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
|
pub struct FrankenPhp;
|
||||||
|
|
||||||
|
impl ServiceTrait for FrankenPhp {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"franken-php"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn env(&self) -> &[&str] {
|
||||||
|
&["FRANKENPHP=1"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Copy, Clone, Debug, PartialEq, EnumString, EnumMessage, EnumIter, IntoStaticStr, Display,
|
Copy, Clone, Debug, PartialEq, EnumString, EnumMessage, EnumIter, IntoStaticStr, Display,
|
||||||
)]
|
)]
|
||||||
|
|
@ -227,6 +250,7 @@ pub enum ServiceType {
|
||||||
/// Ldap admin interface
|
/// Ldap admin interface
|
||||||
LdapAdmin,
|
LdapAdmin,
|
||||||
/// OnlyOffice
|
/// OnlyOffice
|
||||||
|
#[strum(serialize = "onlyoffice", serialize = "only-office")]
|
||||||
OnlyOffice,
|
OnlyOffice,
|
||||||
/// Libre office online
|
/// Libre office online
|
||||||
Office,
|
Office,
|
||||||
|
|
@ -252,6 +276,8 @@ pub enum ServiceType {
|
||||||
Dav,
|
Dav,
|
||||||
/// Sftp external storage
|
/// Sftp external storage
|
||||||
Sftp,
|
Sftp,
|
||||||
|
/// Sftp external storage with public key authentication
|
||||||
|
SftpKey,
|
||||||
/// ownCloud instance for migration
|
/// ownCloud instance for migration
|
||||||
Oc,
|
Oc,
|
||||||
/// Imaginary for preview generation
|
/// Imaginary for preview generation
|
||||||
|
|
@ -281,6 +307,10 @@ pub enum ServiceType {
|
||||||
Redis,
|
Redis,
|
||||||
/// External redis instance with TLS
|
/// External redis instance with TLS
|
||||||
RedisTls,
|
RedisTls,
|
||||||
|
/// Use FrankenPHP instead of PHP-FPM
|
||||||
|
FrankenPhp,
|
||||||
|
/// Webhook test listener
|
||||||
|
Webhook,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
|
|
@ -299,6 +329,7 @@ pub enum Service {
|
||||||
ShardingMigrate(ShardingMigrate),
|
ShardingMigrate(ShardingMigrate),
|
||||||
ShardingMigrateUnset(ShardingMigrateUnset),
|
ShardingMigrateUnset(ShardingMigrateUnset),
|
||||||
Sftp(Sftp),
|
Sftp(Sftp),
|
||||||
|
SftpKey(SftpKey),
|
||||||
Kaspersky(Kaspersky),
|
Kaspersky(Kaspersky),
|
||||||
KasperskyIcap(KasperskyIcap),
|
KasperskyIcap(KasperskyIcap),
|
||||||
Clam(Clam),
|
Clam(Clam),
|
||||||
|
|
@ -310,6 +341,8 @@ pub enum Service {
|
||||||
Mail(Mail),
|
Mail(Mail),
|
||||||
Redis(Redis),
|
Redis(Redis),
|
||||||
RedisTls(RedisTls),
|
RedisTls(RedisTls),
|
||||||
|
FrankenPhp(FrankenPhp),
|
||||||
|
Webhook(Webhook),
|
||||||
Preset(PresetService),
|
Preset(PresetService),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,6 +373,7 @@ impl Service {
|
||||||
}
|
}
|
||||||
ServiceType::Dav => Some(vec![Service::Dav(Dav)]),
|
ServiceType::Dav => Some(vec![Service::Dav(Dav)]),
|
||||||
ServiceType::Sftp => Some(vec![Service::Sftp(Sftp)]),
|
ServiceType::Sftp => Some(vec![Service::Sftp(Sftp)]),
|
||||||
|
ServiceType::SftpKey => Some(vec![Service::SftpKey(SftpKey)]),
|
||||||
ServiceType::Oc => Some(vec![Service::Oc(Oc)]),
|
ServiceType::Oc => Some(vec![Service::Oc(Oc)]),
|
||||||
ServiceType::Imaginary => Some(vec![Service::Imaginary(Imaginary)]),
|
ServiceType::Imaginary => Some(vec![Service::Imaginary(Imaginary)]),
|
||||||
ServiceType::Kaspersky => Some(vec![Service::Kaspersky(Kaspersky)]),
|
ServiceType::Kaspersky => Some(vec![Service::Kaspersky(Kaspersky)]),
|
||||||
|
|
@ -352,6 +386,8 @@ impl Service {
|
||||||
ServiceType::Mail => Some(vec![Service::Mail(Mail)]),
|
ServiceType::Mail => Some(vec![Service::Mail(Mail)]),
|
||||||
ServiceType::Redis => Some(vec![Service::Redis(Redis)]),
|
ServiceType::Redis => Some(vec![Service::Redis(Redis)]),
|
||||||
ServiceType::RedisTls => Some(vec![Service::RedisTls(RedisTls)]),
|
ServiceType::RedisTls => Some(vec![Service::RedisTls(RedisTls)]),
|
||||||
|
ServiceType::FrankenPhp => Some(vec![Service::FrankenPhp(FrankenPhp)]),
|
||||||
|
ServiceType::Webhook => Some(vec![Service::Webhook(Webhook)]),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
presets
|
presets
|
||||||
|
|
@ -414,15 +450,29 @@ impl ServiceTrait for PresetService {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
let preset =
|
let preset =
|
||||||
get_preset(&config.preset, &self.0).ok_or_else(|| Report::msg("invalid preset"))?;
|
get_preset(&config.preset, &self.0).ok_or_else(|| Report::msg("invalid preset"))?;
|
||||||
let mut commands: Vec<_> = preset
|
let mut commands: Vec<_> = preset
|
||||||
.apps
|
.apps
|
||||||
.iter()
|
.iter()
|
||||||
.map(|app| format!("occ app:enable {app} --force"))
|
.map(|app| {
|
||||||
|
vec![
|
||||||
|
"occ".into(),
|
||||||
|
"app:enable".into(),
|
||||||
|
app.clone(),
|
||||||
|
"--force".into(),
|
||||||
|
]
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
commands.extend_from_slice(&preset.commands);
|
for cmnd in &preset.commands {
|
||||||
|
commands.push(shell_words::split(cmnd).into_diagnostic()?);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(commands)
|
Ok(commands)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn split_cmnd(s: &str) -> Vec<String> {
|
||||||
|
s.split(' ').map(String::from).collect()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
use bollard::query_parameters::CreateContainerOptions;
|
use bollard::query_parameters::CreateContainerOptions;
|
||||||
|
|
@ -85,14 +85,13 @@ impl ServiceTrait for ClamIcap {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:app:set files_antivirus av_mode --value=icap".into(),
|
split_cmnd("occ config:app:set files_antivirus av_mode --value=icap"),
|
||||||
"occ config:app:set files_antivirus av_host --value=clamav-icap".into(),
|
split_cmnd("occ config:app:set files_antivirus av_host --value=clamav-icap"),
|
||||||
"occ config:app:set files_antivirus av_port --value=1344".into(),
|
split_cmnd("occ config:app:set files_antivirus av_port --value=1344"),
|
||||||
"occ config:app:set files_antivirus av_icap_request_service --value=avscan".into(),
|
split_cmnd("occ config:app:set files_antivirus av_icap_request_service --value=avscan"),
|
||||||
"occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found"
|
split_cmnd("occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found"),
|
||||||
.into(),
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -171,7 +170,7 @@ impl ServiceTrait for ClamIcapTls {
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
let mut cert = Vec::new();
|
let mut cert = Vec::new();
|
||||||
exec(
|
exec(
|
||||||
docker,
|
docker,
|
||||||
|
|
@ -191,14 +190,13 @@ impl ServiceTrait for ClamIcapTls {
|
||||||
.wrap_err("Failed to write icap certificate")?;
|
.wrap_err("Failed to write icap certificate")?;
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:app:set files_antivirus av_mode --value=icap".into(),
|
split_cmnd("occ config:app:set files_antivirus av_mode --value=icap"),
|
||||||
"occ config:app:set files_antivirus av_icap_tls --value=1".into(),
|
split_cmnd("occ config:app:set files_antivirus av_icap_tls --value=1"),
|
||||||
"occ config:app:set files_antivirus av_host --value=clamav-icap-tls".into(),
|
split_cmnd("occ config:app:set files_antivirus av_host --value=clamav-icap-tls"),
|
||||||
"occ config:app:set files_antivirus av_port --value=1345".into(),
|
split_cmnd("occ config:app:set files_antivirus av_port --value=1345"),
|
||||||
"occ config:app:set files_antivirus av_icap_request_service --value=avscan".into(),
|
split_cmnd("occ config:app:set files_antivirus av_icap_request_service --value=avscan"),
|
||||||
"occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found"
|
split_cmnd("occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found"),
|
||||||
.into(),
|
split_cmnd("occ security:certificates:import data/icap-cert.pem"),
|
||||||
"occ security:certificates:import data/icap-cert.pem".into(),
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -221,10 +219,10 @@ impl ServiceTrait for Clam {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:app:set files_antivirus av_mode --value=executable".into(),
|
split_cmnd("occ config:app:set files_antivirus av_mode --value=executable"),
|
||||||
"occ config:app:set files_antivirus av_path --value=/bin/clamscan".into(),
|
split_cmnd("occ config:app:set files_antivirus av_path --value=/bin/clamscan"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -294,10 +292,12 @@ impl ServiceTrait for ClamSocket {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:app:set files_antivirus av_mode --value=socket".into(),
|
split_cmnd("occ config:app:set files_antivirus av_mode --value=socket"),
|
||||||
"occ config:app:set files_antivirus av_socket --value=tcp://clamav-socket:3310".into(),
|
split_cmnd(
|
||||||
|
"occ config:app:set files_antivirus av_socket --value=tcp://clamav-socket:3310",
|
||||||
|
),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::config::ContainerCreateBody;
|
use bollard::config::ContainerCreateBody;
|
||||||
use bollard::models::{EndpointSettings, HostConfig, NetworkingConfig};
|
use bollard::models::{EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
|
|
@ -76,12 +76,12 @@ impl ServiceTrait for Dav {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ files_external:create dav dav password::password".into(),
|
split_cmnd("occ files_external:create dav dav password::password"),
|
||||||
"occ files_external:config 1 host dav".into(),
|
split_cmnd("occ files_external:config 1 host dav"),
|
||||||
"occ files_external:config 1 user test".into(),
|
split_cmnd("occ files_external:config 1 user test"),
|
||||||
"occ files_external:config 1 password test".into(),
|
split_cmnd("occ files_external:config 1 password test"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::config::NetworkingConfig;
|
use bollard::config::NetworkingConfig;
|
||||||
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig};
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig};
|
||||||
|
|
@ -71,11 +71,14 @@ impl ServiceTrait for Imaginary {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:system:set enabledPreviewProviders 0 --value='OC\\Preview\\Imaginary'"
|
split_cmnd(
|
||||||
.into(),
|
"occ config:system:set enabledPreviewProviders 0 --value='OC\\Preview\\Imaginary'",
|
||||||
"occ config:system:set preview_imaginary_url --value='http://imaginary:9000'".into(),
|
),
|
||||||
|
split_cmnd(
|
||||||
|
"occ config:system:set preview_imaginary_url --value='http://imaginary:9000'",
|
||||||
|
),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::{image_exists, pull_image};
|
use crate::image::{image_exists, pull_image};
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
use bollard::query_parameters::CreateContainerOptions;
|
use bollard::query_parameters::CreateContainerOptions;
|
||||||
|
|
@ -101,11 +101,11 @@ impl ServiceTrait for Kaspersky {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:app:set files_antivirus av_mode --value=kaspersky".into(),
|
split_cmnd("occ config:app:set files_antivirus av_mode --value=kaspersky"),
|
||||||
"occ config:app:set files_antivirus av_host --value=kaspersky".into(),
|
split_cmnd("occ config:app:set files_antivirus av_host --value=kaspersky"),
|
||||||
"occ config:app:set files_antivirus av_port --value=80".into(),
|
split_cmnd("occ config:app:set files_antivirus av_port --value=80"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -187,13 +187,15 @@ impl ServiceTrait for KasperskyIcap {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:app:set files_antivirus av_mode --value=icap".into(),
|
split_cmnd("occ config:app:set files_antivirus av_mode --value=icap"),
|
||||||
"occ config:app:set files_antivirus av_host --value=kaspersky-icap".into(),
|
split_cmnd("occ config:app:set files_antivirus av_host --value=kaspersky-icap"),
|
||||||
"occ config:app:set files_antivirus av_port --value=1344".into(),
|
split_cmnd("occ config:app:set files_antivirus av_port --value=1344"),
|
||||||
"occ config:app:set files_antivirus av_icap_request_service --value=req".into(),
|
split_cmnd("occ config:app:set files_antivirus av_icap_request_service --value=req"),
|
||||||
"occ config:app:set files_antivirus av_icap_response_header --value=X-Virus-ID".into(),
|
split_cmnd(
|
||||||
|
"occ config:app:set files_antivirus av_icap_response_header --value=X-Virus-ID",
|
||||||
|
),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::{HazeConfig, ProxyConfig};
|
use crate::config::{HazeConfig, ProxyConfig};
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::config::NetworkingConfig;
|
use bollard::config::NetworkingConfig;
|
||||||
use bollard::models::{ContainerCreateBody, ContainerState, EndpointSettings, HostConfig};
|
use bollard::models::{ContainerCreateBody, ContainerState, EndpointSettings, HostConfig};
|
||||||
|
|
@ -86,6 +86,46 @@ impl ServiceTrait for Ldap {
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
self.is_running(docker, cloud_id).await
|
self.is_running(docker, cloud_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn post_setup(
|
||||||
|
&self,
|
||||||
|
_docker: &Docker,
|
||||||
|
_cloud_id: &str,
|
||||||
|
_config: &HazeConfig,
|
||||||
|
) -> Result<Vec<Vec<String>>> {
|
||||||
|
Ok(vec![
|
||||||
|
split_cmnd("occ ldap:create-empty-config"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapHost ldap://ldap"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapPort 389"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapAgentName cn=admin,dc=example,dc=org"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapAgentPassword haze"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapBase dc=example,dc=org"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapBaseUsers dc=example,dc=org"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapBaseGroups dc=example,dc=org"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapLoginFilter (&(&(objectclass=inetOrgPerson))(uid=%uid))"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapUserFilter ((objectclass=inetOrgPerson))"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapUserFilterMode 0"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapUserDisplayName sn"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapUserFilterObjectclass inetOrgPerson"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapGroupFilter (&(|(objectclass=posixGroup)))"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapGroupFilterObjectclass posixGroup"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapEmailAttribute email"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapUuidUserAttribute email"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapUuidUserAttribute auto"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapUuidGroupAttribute auto"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapLoginFilterUsername 1"),
|
||||||
|
split_cmnd("occ ldap:set-config s01 ldapConfigurationActive 1"),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start_message(
|
||||||
|
&self,
|
||||||
|
_docker: &Docker,
|
||||||
|
_cloud_id: &str,
|
||||||
|
_proxy: &ProxyConfig,
|
||||||
|
) -> Result<Option<String>> {
|
||||||
|
Ok(Some("\nLdap users provisioned:\n\t'cn=admin,dc=example,dc=org' and password 'haze'\n\t'cn=ldaptest,dc=example,dc=org' and password 'test'\n\nldaptest is available for login\n".into()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
|
@ -185,8 +225,6 @@ impl ServiceTrait for LdapAdmin {
|
||||||
return Err(Report::msg("ldap admin not started"));
|
return Err(Report::msg("ldap admin not started"));
|
||||||
};
|
};
|
||||||
let addr = proxy.addr(&id, IpAddr::from_str(&ip).unwrap());
|
let addr = proxy.addr(&id, IpAddr::from_str(&ip).unwrap());
|
||||||
Ok(Some(format!(
|
Ok(Some(format!("Ldap admin running at: {addr}")))
|
||||||
"Ldap admin running at: {addr} with 'cn=admin,dc=example,dc=org' and password 'haze'"
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
use bollard::query_parameters::CreateContainerOptions;
|
use bollard::query_parameters::CreateContainerOptions;
|
||||||
|
|
@ -70,14 +70,14 @@ impl ServiceTrait for Mail {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ config:system:set mail_smtpmode --value smtp".into(),
|
split_cmnd("occ config:system:set mail_smtpmode --value smtp"),
|
||||||
"occ config:system:set mail_sendmailmode --value smtp".into(),
|
split_cmnd("occ config:system:set mail_sendmailmode --value smtp"),
|
||||||
"occ config:system:set mail_domain --value haze".into(),
|
split_cmnd("occ config:system:set mail_domain --value haze"),
|
||||||
"occ config:system:set mail_smtphost --value mail".into(),
|
split_cmnd("occ config:system:set mail_smtphost --value mail"),
|
||||||
"occ config:system:set mail_smtpport --value 25".into(),
|
split_cmnd("occ config:system:set mail_smtpport --value 25"),
|
||||||
"occ user:setting admin settings email admin@haze".into(),
|
split_cmnd("occ user:setting admin settings email admin@haze"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{
|
use bollard::models::{
|
||||||
ContainerCreateBody, ContainerState, EndpointSettings, HostConfig, NetworkingConfig,
|
ContainerCreateBody, ContainerState, EndpointSettings, HostConfig, NetworkingConfig,
|
||||||
|
|
@ -247,18 +247,18 @@ impl ServiceTrait for ObjectStore {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
match self {
|
match self {
|
||||||
ObjectStore::S3 => Ok(vec![
|
ObjectStore::S3 => Ok(vec![
|
||||||
"occ files_external:create s3 amazons3 amazons3::accesskey".into(),
|
split_cmnd("occ files_external:create s3 amazons3 amazons3::accesskey"),
|
||||||
"occ files_external:config 1 bucket ext".into(),
|
split_cmnd("occ files_external:config 1 bucket ext"),
|
||||||
"occ files_external:config 1 hostname s3".into(),
|
split_cmnd("occ files_external:config 1 hostname s3"),
|
||||||
"occ files_external:config 1 port 9000".into(),
|
split_cmnd("occ files_external:config 1 port 9000"),
|
||||||
"occ files_external:config 1 use_ssl false".into(),
|
split_cmnd("occ files_external:config 1 use_ssl false"),
|
||||||
"occ files_external:config 1 use_path_style true".into(),
|
split_cmnd("occ files_external:config 1 use_path_style true"),
|
||||||
"occ files_external:config 1 key minio".into(),
|
split_cmnd("occ files_external:config 1 key minio"),
|
||||||
"occ files_external:config 1 secret minio123".into(),
|
split_cmnd("occ files_external:config 1 secret minio123"),
|
||||||
"mc alias set s3 http://s3:9000 minio minio123".into(),
|
split_cmnd("mc alias set s3 http://s3:9000 minio minio123"),
|
||||||
]),
|
]),
|
||||||
// ObjectStore::S3s => Ok(vec![
|
// ObjectStore::S3s => Ok(vec![
|
||||||
// "occ files_external:create s3 amazons3 amazons3::accesskey".into(),
|
// "occ files_external:create s3 amazons3 amazons3::accesskey".into(),
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ impl ServiceTrait for Oc {
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
if let Some(ip) = self.get_ips(docker, cloud_id).await?.next() {
|
if let Some(ip) = self.get_ips(docker, cloud_id).await?.next() {
|
||||||
let container = self.container_name(cloud_id).unwrap();
|
let container = self.container_name(cloud_id).unwrap();
|
||||||
let addr = config.proxy.addr(&container, ip);
|
let addr = config.proxy.addr(&container, ip);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,23 @@ impl ServiceTrait for Office {
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
_options: &CloudOptions,
|
_options: &CloudOptions,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<String>> {
|
||||||
|
let network_info = docker
|
||||||
|
.inspect_network(network, None)
|
||||||
|
.await
|
||||||
|
.into_diagnostic()?;
|
||||||
|
let gateway = network_info
|
||||||
|
.ipam
|
||||||
|
.as_ref()
|
||||||
|
.ok_or_else(|| Report::msg("Network has no ip info"))?
|
||||||
|
.config
|
||||||
|
.as_deref()
|
||||||
|
.ok_or_else(|| Report::msg("Network has no ip info"))?
|
||||||
|
.first()
|
||||||
|
.ok_or_else(|| Report::msg("Network has no ip info"))?
|
||||||
|
.gateway
|
||||||
|
.as_deref()
|
||||||
|
.ok_or_else(|| Report::msg("Network has no ip info"))?;
|
||||||
|
|
||||||
let image = "collabora/code";
|
let image = "collabora/code";
|
||||||
pull_image(docker, image).await?;
|
pull_image(docker, image).await?;
|
||||||
let container_id = self.container_name(cloud_id).unwrap();
|
let container_id = self.container_name(cloud_id).unwrap();
|
||||||
|
|
@ -39,28 +56,31 @@ impl ServiceTrait for Office {
|
||||||
name: Some(container_id.clone()),
|
name: Some(container_id.clone()),
|
||||||
..CreateContainerOptions::default()
|
..CreateContainerOptions::default()
|
||||||
});
|
});
|
||||||
let mut env = vec!["extra_params=--o:ssl.enable=false --o:ssl.termination=true"];
|
let mut env =
|
||||||
|
vec![r#"extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:net.frame_ancestors=*"#.to_string()];
|
||||||
|
|
||||||
|
let proxy_base = &config.proxy.address;
|
||||||
let clean_id = container_id.strip_prefix("haze-").unwrap_or(&container_id);
|
let clean_id = container_id.strip_prefix("haze-").unwrap_or(&container_id);
|
||||||
let server_name_opt = match (&config.proxy.address, config.proxy.https) {
|
if !proxy_base.is_empty() {
|
||||||
(public, true) if !public.is_empty() => {
|
env.push(format!("server_name={clean_id}.{}", config.proxy.address));
|
||||||
format!("server_name={clean_id}.{public}")
|
|
||||||
}
|
}
|
||||||
(public, false) if !public.is_empty() => {
|
|
||||||
format!("server_name={clean_id}.{public}")
|
|
||||||
}
|
|
||||||
_ => "".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if !server_name_opt.is_empty() {
|
let clean_cloud_id = cloud_id.strip_prefix("haze-").unwrap_or(cloud_id);
|
||||||
env.push(&server_name_opt);
|
let hosts = if proxy_base.is_empty() {
|
||||||
}
|
vec![]
|
||||||
|
} else {
|
||||||
|
vec![
|
||||||
|
format!("{proxy_base}:{gateway}"),
|
||||||
|
format!("{clean_cloud_id}.{proxy_base}:{gateway}"),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
let config = ContainerCreateBody {
|
let config = ContainerCreateBody {
|
||||||
image: Some(image.into()),
|
image: Some(image.into()),
|
||||||
env: Some(env.into_iter().map(String::from).collect()),
|
env: Some(env),
|
||||||
host_config: Some(HostConfig {
|
host_config: Some(HostConfig {
|
||||||
network_mode: Some(network.to_string()),
|
network_mode: Some(network.to_string()),
|
||||||
|
extra_hosts: Some(hosts),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
labels: Some(hashmap! {
|
labels: Some(hashmap! {
|
||||||
|
|
@ -99,7 +119,7 @@ impl ServiceTrait for Office {
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
let container = &self.container_name(cloud_id).unwrap();
|
let container = &self.container_name(cloud_id).unwrap();
|
||||||
let info = docker
|
let info = docker
|
||||||
.inspect_container(container, None)
|
.inspect_container(container, None)
|
||||||
|
|
@ -127,19 +147,27 @@ impl ServiceTrait for Office {
|
||||||
} else {
|
} else {
|
||||||
return Err(Report::msg("office not started"));
|
return Err(Report::msg("office not started"));
|
||||||
};
|
};
|
||||||
|
let public = config
|
||||||
|
.proxy
|
||||||
|
.addr_with_port(container, ip, self.proxy_port());
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
format!(
|
vec![
|
||||||
r#"occ config:app:set richdocuments wopi_url --value="http://{}:9980""#,
|
"occ".into(),
|
||||||
ip
|
"config:app:set".into(),
|
||||||
),
|
"richdocuments".into(),
|
||||||
format!(
|
"public_wopi_url".into(),
|
||||||
r#"occ config:app:set richdocuments public_wopi_url --value="{}""#,
|
"--value".into(),
|
||||||
config.proxy.addr_with_port(container, ip, 9980)
|
public,
|
||||||
),
|
],
|
||||||
format!(
|
vec![
|
||||||
r#"occ config:app:set richdocuments wopi_root --value="http://{}""#,
|
"occ".into(),
|
||||||
cloud_id
|
"richdocuments:setup".into(),
|
||||||
),
|
"--wopi-url".into(),
|
||||||
|
"http://office:9980".into(),
|
||||||
|
"--callback-url".into(),
|
||||||
|
"http://cloud".into(),
|
||||||
|
],
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::exec::exec;
|
use crate::exec::exec;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{
|
use bollard::models::{
|
||||||
ContainerCreateBody, ContainerState, EndpointSettings, HostConfig, NetworkingConfig,
|
ContainerCreateBody, ContainerState, EndpointSettings, HostConfig, NetworkingConfig,
|
||||||
|
|
@ -82,7 +82,7 @@ impl ServiceTrait for OnlyOffice {
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
let info = docker
|
let info = docker
|
||||||
.inspect_container(&self.container_name(cloud_id).unwrap(), None)
|
.inspect_container(&self.container_name(cloud_id).unwrap(), None)
|
||||||
.await
|
.await
|
||||||
|
|
@ -137,16 +137,44 @@ impl ServiceTrait for OnlyOffice {
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
format!("occ config:app:set onlyoffice DocumentServerUrl --value {addr}/"),
|
vec![
|
||||||
format!("occ config:app:set onlyoffice jwt_secret --value {secret}"),
|
"occ".into(),
|
||||||
"occ onlyoffice:documentserver --check".into(),
|
"config:app:set".into(),
|
||||||
|
"onlyoffice".into(),
|
||||||
|
"DocumentServerUrl".into(),
|
||||||
|
"--value".into(),
|
||||||
|
addr,
|
||||||
|
],
|
||||||
|
vec![
|
||||||
|
"occ".into(),
|
||||||
|
"config:app:set".into(),
|
||||||
|
"onlyoffice".into(),
|
||||||
|
"jwt_secret".into(),
|
||||||
|
"--value".into(),
|
||||||
|
secret.into(),
|
||||||
|
],
|
||||||
|
split_cmnd("occ onlyoffice:documentserver --check"),
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
format!("occ config:app:set onlyoffice DocumentServerUrl --value https://{ip}/"),
|
vec![
|
||||||
"occ config:app:set onlyoffice verify_peer_off --value true".into(),
|
"occ".into(),
|
||||||
format!("occ config:app:set onlyoffice jwt_secret --value {secret}"),
|
"config:app:set".into(),
|
||||||
"occ onlyoffice:documentserver --check".into(),
|
"onlyoffice".into(),
|
||||||
|
"DocumentServerUrl".into(),
|
||||||
|
"--value".into(),
|
||||||
|
format!("https://{ip}/"),
|
||||||
|
],
|
||||||
|
split_cmnd("occ config:app:set onlyoffice verify_peer_off --value true"),
|
||||||
|
vec![
|
||||||
|
"occ".into(),
|
||||||
|
"config:app:set".into(),
|
||||||
|
"onlyoffice".into(),
|
||||||
|
"jwt_secret".into(),
|
||||||
|
"--value".into(),
|
||||||
|
secret.into(),
|
||||||
|
],
|
||||||
|
split_cmnd("occ onlyoffice:documentserver --check"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ impl ServiceTrait for NotifyPush {
|
||||||
docker: &Docker,
|
docker: &Docker,
|
||||||
cloud_id: &str,
|
cloud_id: &str,
|
||||||
config: &HazeConfig,
|
config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
let mut ips: Vec<_> = self.get_ips(docker, cloud_id).await?.collect();
|
let mut ips: Vec<_> = self.get_ips(docker, cloud_id).await?.collect();
|
||||||
if let Ok(local_interfaces) = list_afinet_netifas() {
|
if let Ok(local_interfaces) = list_afinet_netifas() {
|
||||||
ips.extend(local_interfaces.into_iter().map(|(_, ip)| ip));
|
ips.extend(local_interfaces.into_iter().map(|(_, ip)| ip));
|
||||||
|
|
@ -97,10 +97,14 @@ impl ServiceTrait for NotifyPush {
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, ip)| {
|
.map(|(i, ip)| {
|
||||||
format!(
|
vec![
|
||||||
"occ config:system:set trusted_proxies {} --value {ip}",
|
"occ".into(),
|
||||||
i + 1
|
"config:system:set".into(),
|
||||||
)
|
"trusted_proxies".into(),
|
||||||
|
(i + 1).to_string(),
|
||||||
|
"--value".into(),
|
||||||
|
ip.to_string(),
|
||||||
|
]
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
@ -108,7 +112,7 @@ impl ServiceTrait for NotifyPush {
|
||||||
config
|
config
|
||||||
.proxy
|
.proxy
|
||||||
.addr_with_port(&self.container_name(cloud_id).unwrap(), ips[0], 7867);
|
.addr_with_port(&self.container_name(cloud_id).unwrap(), ips[0], 7867);
|
||||||
commands.push(format!("occ notify_push:setup {}", addr));
|
commands.push(vec!["occ".into(), "notify_push:setup".into(), addr]);
|
||||||
Ok(commands)
|
Ok(commands)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
use bollard::query_parameters::CreateContainerOptions;
|
use bollard::query_parameters::CreateContainerOptions;
|
||||||
|
|
@ -70,7 +70,13 @@ impl ServiceTrait for Redis {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec!["occ config:system:set redis host --value redis".into()])
|
Ok(vec![split_cmnd(
|
||||||
|
"occ config:system:set redis host --value redis",
|
||||||
|
)])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_shell(&self) -> &'static str {
|
||||||
|
"sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
use bollard::query_parameters::CreateContainerOptions;
|
use bollard::query_parameters::CreateContainerOptions;
|
||||||
use bollard::Docker;
|
use bollard::Docker;
|
||||||
use maplit::hashmap;
|
use maplit::hashmap;
|
||||||
use miette::IntoDiagnostic;
|
use miette::{Context, IntoDiagnostic};
|
||||||
|
use std::fs::{create_dir_all, write};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct Sftp;
|
pub struct Sftp;
|
||||||
|
|
@ -50,7 +51,10 @@ impl ServiceTrait for Sftp {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
cmd: Some(vec!["test:test:::data".into()]),
|
cmd: Some(vec![
|
||||||
|
"test:test:::data".into(),
|
||||||
|
"ldaptest:test:::data".into(),
|
||||||
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let id = docker
|
let id = docker
|
||||||
|
|
@ -75,13 +79,119 @@ impl ServiceTrait for Sftp {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ files_external:create sftp sftp password::password".into(),
|
split_cmnd("occ files_external:create sftp sftp password::password"),
|
||||||
"occ files_external:config 1 host sftp".into(),
|
split_cmnd("occ files_external:config 1 host sftp"),
|
||||||
"occ files_external:config 1 user test".into(),
|
split_cmnd("occ files_external:config 1 user test"),
|
||||||
"occ files_external:config 1 root data".into(),
|
split_cmnd("occ files_external:config 1 root data"),
|
||||||
"occ files_external:config 1 password test".into(),
|
split_cmnd("occ files_external:config 1 password test"),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
pub struct SftpKey;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl ServiceTrait for SftpKey {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"sftp-key"
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn spawn(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
network: &str,
|
||||||
|
config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
|
) -> Result<Vec<String>> {
|
||||||
|
let image = "atmoz/sftp:alpine";
|
||||||
|
pull_image(docker, image).await?;
|
||||||
|
let options = Some(CreateContainerOptions {
|
||||||
|
name: self.container_name(cloud_id),
|
||||||
|
..CreateContainerOptions::default()
|
||||||
|
});
|
||||||
|
let key_dir = config.work_dir.join("certificates/sftp");
|
||||||
|
create_dir_all(&key_dir)
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to create sftp certificate directory")?;
|
||||||
|
let private_path = key_dir.join("id_rsa");
|
||||||
|
let public_path = key_dir.join("id_rsa.pub");
|
||||||
|
let private_key = include_str!("../../certificates/sftp/id_rsa");
|
||||||
|
let public_key = include_str!("../../certificates/sftp/id_rsa.pub");
|
||||||
|
if !private_path.exists() {
|
||||||
|
write(&private_path, private_key)
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to write sftp client certificate")?;
|
||||||
|
}
|
||||||
|
if !public_path.exists() {
|
||||||
|
write(&public_path, public_key)
|
||||||
|
.into_diagnostic()
|
||||||
|
.wrap_err("Failed to write sftp client key")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let volumes = vec![format!("{public_path}:/home/test/.ssh/keys/id_rsa:ro")];
|
||||||
|
|
||||||
|
let config = ContainerCreateBody {
|
||||||
|
image: Some(image.into()),
|
||||||
|
host_config: Some(HostConfig {
|
||||||
|
network_mode: Some(network.to_string()),
|
||||||
|
binds: Some(volumes),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
labels: Some(hashmap! {
|
||||||
|
"haze-type".into() => self.name().into(),
|
||||||
|
"haze-cloud-id".into() => cloud_id.into(),
|
||||||
|
}),
|
||||||
|
networking_config: Some(NetworkingConfig {
|
||||||
|
endpoints_config: Some(hashmap! {
|
||||||
|
network.into() => EndpointSettings {
|
||||||
|
aliases: Some(vec![self.name().to_string()]),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
cmd: Some(vec!["test::::data".into()]),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let id = docker
|
||||||
|
.create_container(options, config)
|
||||||
|
.await
|
||||||
|
.into_diagnostic()?
|
||||||
|
.id;
|
||||||
|
docker.start_container(&id, None).await.into_diagnostic()?;
|
||||||
|
Ok(vec![id])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn container_name(&self, cloud_id: &str) -> Option<String> {
|
||||||
|
Some(format!("{}-sftp-key", cloud_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apps(&self) -> &'static [&'static str] {
|
||||||
|
&["files_external"]
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn post_setup(
|
||||||
|
&self,
|
||||||
|
_docker: &Docker,
|
||||||
|
_cloud_id: &str,
|
||||||
|
_config: &HazeConfig,
|
||||||
|
) -> Result<Vec<Vec<String>>> {
|
||||||
|
Ok(vec![
|
||||||
|
split_cmnd("occ files_external:create sftp sftp publickey::rsa_private"),
|
||||||
|
split_cmnd("occ files_external:config 1 host sftp-key"),
|
||||||
|
split_cmnd("occ files_external:config 1 user test"),
|
||||||
|
split_cmnd("occ files_external:config 1 root data"),
|
||||||
|
vec![
|
||||||
|
"occ".into(),
|
||||||
|
"files_external:config".into(),
|
||||||
|
"--value-from-file".into(),
|
||||||
|
"1".into(),
|
||||||
|
"private_key".into(),
|
||||||
|
"/certificates/sftp/id_rsa".into(),
|
||||||
|
],
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::cloud::CloudOptions;
|
use crate::cloud::CloudOptions;
|
||||||
use crate::config::HazeConfig;
|
use crate::config::HazeConfig;
|
||||||
use crate::image::pull_image;
|
use crate::image::pull_image;
|
||||||
use crate::service::ServiceTrait;
|
use crate::service::{split_cmnd, ServiceTrait};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
use bollard::query_parameters::CreateContainerOptions;
|
use bollard::query_parameters::CreateContainerOptions;
|
||||||
|
|
@ -40,8 +40,10 @@ impl ServiceTrait for Smb {
|
||||||
}),
|
}),
|
||||||
env: Some(vec![
|
env: Some(vec![
|
||||||
"ACCOUNT_test=test".into(),
|
"ACCOUNT_test=test".into(),
|
||||||
|
"ACCOUNT_ldaptest=test".into(),
|
||||||
"UID_test=1000".into(),
|
"UID_test=1000".into(),
|
||||||
"SAMBA_VOLUME_CONFIG_test=[test]; path=/tmp; valid users = test; guest ok = no; read only = no; browseable = yes".into(),
|
"SAMBA_VOLUME_CONFIG_test=[test]; path=/tmp; valid users = test; guest ok = no; read only = no; browseable = yes".into(),
|
||||||
|
"SAMBA_VOLUME_CONFIG_ldaptest=[ldaptest]; path=/tmp; valid users = ldaptest; guest ok = no; read only = no; browseable = yes".into(),
|
||||||
]),
|
]),
|
||||||
labels: Some(hashmap! {
|
labels: Some(hashmap! {
|
||||||
"haze-type".into() => self.name().into(),
|
"haze-type".into() => self.name().into(),
|
||||||
|
|
@ -79,13 +81,17 @@ impl ServiceTrait for Smb {
|
||||||
_docker: &Docker,
|
_docker: &Docker,
|
||||||
_cloud_id: &str,
|
_cloud_id: &str,
|
||||||
_config: &HazeConfig,
|
_config: &HazeConfig,
|
||||||
) -> Result<Vec<String>> {
|
) -> Result<Vec<Vec<String>>> {
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
"occ files_external:create smb smb password::password".into(),
|
split_cmnd("occ files_external:create smb smb password::password"),
|
||||||
"occ files_external:config 1 host smb".into(),
|
split_cmnd("occ files_external:config 1 host smb"),
|
||||||
"occ files_external:config 1 user test".into(),
|
split_cmnd("occ files_external:config 1 user test"),
|
||||||
"occ files_external:config 1 password test".into(),
|
split_cmnd("occ files_external:config 1 password test"),
|
||||||
"occ files_external:config 1 share test".into(),
|
split_cmnd("occ files_external:config 1 share test"),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn exec_shell(&self) -> &'static str {
|
||||||
|
"sh"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
75
src/service/webhook.rs
Normal file
75
src/service/webhook.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
use crate::cloud::CloudOptions;
|
||||||
|
use crate::config::HazeConfig;
|
||||||
|
use crate::image::pull_image;
|
||||||
|
use crate::service::ServiceTrait;
|
||||||
|
use crate::Result;
|
||||||
|
use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig};
|
||||||
|
use bollard::query_parameters::CreateContainerOptions;
|
||||||
|
use bollard::Docker;
|
||||||
|
use maplit::hashmap;
|
||||||
|
use miette::IntoDiagnostic;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
|
pub struct Webhook;
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl ServiceTrait for Webhook {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"webhook"
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn spawn(
|
||||||
|
&self,
|
||||||
|
docker: &Docker,
|
||||||
|
cloud_id: &str,
|
||||||
|
network: &str,
|
||||||
|
_config: &HazeConfig,
|
||||||
|
_options: &CloudOptions,
|
||||||
|
) -> Result<Vec<String>> {
|
||||||
|
let image = "ghcr.io/tarampampam/webhook-tester";
|
||||||
|
pull_image(docker, image).await?;
|
||||||
|
let options = Some(CreateContainerOptions {
|
||||||
|
name: self.container_name(cloud_id),
|
||||||
|
..CreateContainerOptions::default()
|
||||||
|
});
|
||||||
|
let config = ContainerCreateBody {
|
||||||
|
image: Some(image.into()),
|
||||||
|
host_config: Some(HostConfig {
|
||||||
|
network_mode: Some(network.to_string()),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
labels: Some(hashmap! {
|
||||||
|
"haze-type".into() => self.name().into(),
|
||||||
|
"haze-cloud-id".into() => cloud_id.into(),
|
||||||
|
}),
|
||||||
|
networking_config: Some(NetworkingConfig {
|
||||||
|
endpoints_config: Some(hashmap! {
|
||||||
|
network.into() => EndpointSettings {
|
||||||
|
aliases: Some(vec![self.name().to_string()]),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let id = docker
|
||||||
|
.create_container(options, config)
|
||||||
|
.await
|
||||||
|
.into_diagnostic()?
|
||||||
|
.id;
|
||||||
|
docker.start_container(&id, None).await.into_diagnostic()?;
|
||||||
|
Ok(vec![id])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn container_name(&self, cloud_id: &str) -> Option<String> {
|
||||||
|
Some(format!("{}-webhook", cloud_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn proxy_port(&self) -> u16 {
|
||||||
|
8080
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_shell(&self) -> &'static str {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -122,7 +122,7 @@ pub async fn download_nc(config: &HazeConfig, version: &str) -> Result<Utf8PathB
|
||||||
}
|
}
|
||||||
hash_bar.finish();
|
hash_bar.finish();
|
||||||
|
|
||||||
let extract_bar = ProgressBar::new_spinner().with_message("Extracing");
|
let extract_bar = ProgressBar::new_spinner().with_message("Extracting");
|
||||||
extract_bar.enable_steady_tick(Duration::from_millis(100));
|
extract_bar.enable_steady_tick(Duration::from_millis(100));
|
||||||
let extract_bar = progress.add(extract_bar);
|
let extract_bar = progress.add(extract_bar);
|
||||||
let mut archive = ZipArchive::new(Cursor::new(archive)).into_diagnostic()?;
|
let mut archive = ZipArchive::new(Cursor::new(archive)).into_diagnostic()?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue