Compare commits
No commits in common. "55e3f97946ee47728d0ae298b92504a378967645" and "d3ef4d2030db2b75bceb1d120e775df64a7fad25" have entirely different histories.
55e3f97946
...
d3ef4d2030
13 changed files with 46 additions and 957 deletions
366
Cargo.lock
generated
366
Cargo.lock
generated
|
|
@ -294,12 +294,6 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.44"
|
||||
|
|
@ -382,7 +376,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
|
|
@ -631,10 +625,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -644,11 +636,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi 5.3.0",
|
||||
"wasip2",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -744,13 +734,12 @@ dependencies = [
|
|||
"futures",
|
||||
"hex",
|
||||
"hmac",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"sqlx",
|
||||
"tokio",
|
||||
"tower-http 0.5.2",
|
||||
"tower-http",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"uuid",
|
||||
|
|
@ -847,24 +836,6 @@ dependencies = [
|
|||
"pin-utils",
|
||||
"smallvec",
|
||||
"tokio",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.27.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
|
||||
dependencies = [
|
||||
"http",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"rustls 0.23.37",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
"webpki-roots 1.0.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -873,21 +844,13 @@ version = "0.1.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"ipnet",
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1043,22 +1006,6 @@ dependencies = [
|
|||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2"
|
||||
|
||||
[[package]]
|
||||
name = "iri-string"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.17"
|
||||
|
|
@ -1152,12 +1099,6 @@ version = "0.4.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "lru-slab"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.2.0"
|
||||
|
|
@ -1242,7 +1183,7 @@ dependencies = [
|
|||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"smallvec",
|
||||
"zeroize",
|
||||
]
|
||||
|
|
@ -1427,61 +1368,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cfg_aliases",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls 0.23.37",
|
||||
"socket2",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"getrandom 0.3.4",
|
||||
"lru-slab",
|
||||
"rand 0.9.2",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustls 0.23.37",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.18",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
|
|
@ -1510,18 +1396,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.5",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1531,17 +1407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.5",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1553,15 +1419,6 @@ dependencies = [
|
|||
"getrandom 0.2.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
|
|
@ -1597,44 +1454,6 @@ version = "0.8.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-util",
|
||||
"js-sys",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls 0.23.37",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower",
|
||||
"tower-http 0.6.8",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"webpki-roots 1.0.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
|
|
@ -1662,19 +1481,13 @@ dependencies = [
|
|||
"num-traits",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
"signature",
|
||||
"spki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.4"
|
||||
|
|
@ -1695,24 +1508,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-webpki 0.101.7",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki 0.103.10",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.4"
|
||||
|
|
@ -1722,16 +1521,6 @@ dependencies = [
|
|||
"base64 0.21.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
|
||||
dependencies = [
|
||||
"web-time",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.7"
|
||||
|
|
@ -1742,17 +1531,6 @@ dependencies = [
|
|||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
|
|
@ -1907,7 +1685,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core 0.6.4",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2002,19 +1780,19 @@ dependencies = [
|
|||
"once_cell",
|
||||
"paste",
|
||||
"percent-encoding",
|
||||
"rustls 0.21.12",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"sqlformat",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tracing",
|
||||
"url",
|
||||
"webpki-roots 0.25.4",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2086,7 +1864,7 @@ dependencies = [
|
|||
"memchr",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rsa",
|
||||
"serde",
|
||||
"sha1",
|
||||
|
|
@ -2094,7 +1872,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
|
@ -2126,14 +1904,14 @@ dependencies = [
|
|||
"md-5",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
"sqlx-core",
|
||||
"stringprep",
|
||||
"thiserror 1.0.69",
|
||||
"thiserror",
|
||||
"tracing",
|
||||
"whoami",
|
||||
]
|
||||
|
|
@ -2212,9 +1990,6 @@ name = "sync_wrapper"
|
|||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synstructure"
|
||||
|
|
@ -2246,16 +2021,7 @@ version = "1.0.69"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.18",
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2269,17 +2035,6 @@ dependencies = [
|
|||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.9"
|
||||
|
|
@ -2342,16 +2097,6 @@ dependencies = [
|
|||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
|
||||
dependencies = [
|
||||
"rustls 0.23.37",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.18"
|
||||
|
|
@ -2396,24 +2141,6 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-http"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"iri-string",
|
||||
"pin-project-lite",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.3"
|
||||
|
|
@ -2488,12 +2215,6 @@ dependencies = [
|
|||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
|
|
@ -2570,7 +2291,6 @@ dependencies = [
|
|||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2614,15 +2334,6 @@ version = "0.9.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||
dependencies = [
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
|
|
@ -2666,20 +2377,6 @@ dependencies = [
|
|||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.114"
|
||||
|
|
@ -2746,41 +2443,12 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.91"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-time"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.25.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "whoami"
|
||||
version = "1.6.1"
|
||||
|
|
|
|||
|
|
@ -9,4 +9,3 @@
|
|||
* Integrate with git using github webhooks or add your own git remote
|
||||
* automatic redeployment after git push
|
||||
* Builtin ssl. Automatically provisioned using let's encrypt.
|
||||
* Caddy reverse proxy
|
||||
|
|
@ -45,9 +45,7 @@ ssh pi@hiypi.local
|
|||
|
||||
```bash
|
||||
sudo apt update && sudo apt full-upgrade -y
|
||||
sudo apt install -y git curl ufw fail2ban unattended-upgrades podman python3 pipx aardvark-dns sqlite3
|
||||
pipx install podman-compose
|
||||
pipx ensurepath
|
||||
sudo apt install -y git curl ufw fail2ban unattended-upgrades
|
||||
```
|
||||
|
||||
### Static IP (optional but recommended)
|
||||
|
|
|
|||
|
|
@ -15,15 +15,3 @@ POSTGRES_PASSWORD=changeme
|
|||
# Forgejo (optional — only needed if you add the forgejo service to docker-compose.yml).
|
||||
FORGEJO_DB_PASSWORD=changeme
|
||||
FORGEJO_DOMAIN=git.yourdomain.com
|
||||
# Actions runner registration token — obtain from Forgejo:
|
||||
# Site Administration → Actions → Runners → Create new runner
|
||||
FORGEJO_RUNNER_TOKEN=
|
||||
|
||||
# ── Backup (infra/backup.sh) ──────────────────────────────────────────────────
|
||||
# Local directory to store backup archives.
|
||||
HIY_BACKUP_DIR=/mnt/usb/hiy-backups
|
||||
# Optional rclone remote (e.g. "b2:mybucket/hiy", "s3:mybucket/hiy").
|
||||
# Requires rclone installed and configured. Leave blank to skip remote upload.
|
||||
HIY_BACKUP_REMOTE=
|
||||
# How many days to keep local archives (default 30).
|
||||
HIY_BACKUP_RETAIN_DAYS=30
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# auto-update.sh — pull latest changes and restart affected services.
|
||||
# Run by the hiy-update.timer systemd user unit every 5 minutes.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
log() { echo "[hiy-update] $(date '+%H:%M:%S') $*"; }
|
||||
|
||||
cd "$REPO_ROOT"
|
||||
|
||||
# Fetch without touching the working tree.
|
||||
git fetch origin 2>&1 | sed 's/^/[git] /' || { log "git fetch failed — skipping"; exit 0; }
|
||||
|
||||
LOCAL=$(git rev-parse HEAD)
|
||||
REMOTE=$(git rev-parse "@{u}" 2>/dev/null || echo "$LOCAL")
|
||||
|
||||
if [ "$LOCAL" = "$REMOTE" ]; then
|
||||
log "Already up to date ($LOCAL)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "New commits detected — pulling ($LOCAL → $REMOTE)…"
|
||||
git pull 2>&1 | sed 's/^/[git] /'
|
||||
|
||||
# Determine which services need restarting based on what changed.
|
||||
CHANGED=$(git diff --name-only "$LOCAL" "$REMOTE")
|
||||
log "Changed files: $(echo "$CHANGED" | tr '\n' ' ')"
|
||||
|
||||
# Always rebuild the server if any server-side code changed.
|
||||
SERVER_CHANGED=$(echo "$CHANGED" | grep -E '^server/|^Cargo' || true)
|
||||
COMPOSE_CHANGED=$(echo "$CHANGED" | grep '^infra/docker-compose' || true)
|
||||
CADDY_CHANGED=$(echo "$CHANGED" | grep '^proxy/Caddyfile' || true)
|
||||
|
||||
COMPOSE_CMD="podman compose --env-file $REPO_ROOT/.env -f $SCRIPT_DIR/docker-compose.yml"
|
||||
|
||||
if [ -n "$COMPOSE_CHANGED" ]; then
|
||||
log "docker-compose.yml changed — restarting full stack…"
|
||||
$COMPOSE_CMD up -d
|
||||
elif [ -n "$SERVER_CHANGED" ]; then
|
||||
log "Server code changed — rebuilding server…"
|
||||
$COMPOSE_CMD up -d --build server
|
||||
elif [ -n "$CADDY_CHANGED" ]; then
|
||||
log "Caddyfile changed — reloading Caddy…"
|
||||
$COMPOSE_CMD exec caddy caddy reload --config /etc/caddy/Caddyfile --adapter caddyfile
|
||||
else
|
||||
log "No service restart needed for these changes."
|
||||
fi
|
||||
|
||||
log "Done."
|
||||
118
infra/backup.sh
118
infra/backup.sh
|
|
@ -3,32 +3,21 @@
|
|||
#
|
||||
# What is backed up:
|
||||
# 1. SQLite database (hiy.db) — apps, deploys, env vars, users
|
||||
# 2. Env files — per-deploy decrypted env files
|
||||
# 2. Env files directory — decrypted env files written per deploy
|
||||
# 3. Git repos — bare repos for git-push deploys
|
||||
# 4. Postgres — pg_dumpall (hiy + forgejo databases)
|
||||
# 5. Forgejo data volume — repositories, avatars, LFS objects
|
||||
# 6. Caddy TLS certificates — caddy-data volume
|
||||
# 7. .env file — secrets (handle the archive with care)
|
||||
#
|
||||
# Destination options (mutually exclusive; set one):
|
||||
# HIY_BACKUP_DIR — local path (e.g. /mnt/usb/hiy-backups, default /tmp/hiy-backups)
|
||||
# HIY_BACKUP_REMOTE — rclone remote:path (e.g. "b2:mybucket/hiy")
|
||||
# requires rclone installed and configured
|
||||
#
|
||||
# Retention: 30 days local (remote retention managed by the storage provider).
|
||||
# Retention: 30 days (local only; remote retention is managed by the storage provider)
|
||||
#
|
||||
# Suggested cron (run as the same user that owns the containers):
|
||||
# Suggested cron (run as the same user as hiy-server):
|
||||
# 0 3 * * * /path/to/infra/backup.sh >> /var/log/hiy-backup.log 2>&1
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── Load .env ──────────────────────────────────────────────────────────────────
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ENV_FILE="${SCRIPT_DIR}/../.env"
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
set -a; source "$ENV_FILE"; set +a
|
||||
fi
|
||||
|
||||
# ── Config ─────────────────────────────────────────────────────────────────────
|
||||
HIY_DATA_DIR="${HIY_DATA_DIR:-/data}"
|
||||
BACKUP_DIR="${HIY_BACKUP_DIR:-/tmp/hiy-backups}"
|
||||
|
|
@ -45,90 +34,30 @@ log "=== HIY Backup ==="
|
|||
log "Data dir: ${HIY_DATA_DIR}"
|
||||
log "Staging: ${STAGING}"
|
||||
|
||||
# ── 1. Stage files ─────────────────────────────────────────────────────────────
|
||||
mkdir -p "${STAGING}"
|
||||
|
||||
# ── Helper: find a running container by compose service label ──────────────────
|
||||
find_container() {
|
||||
local service="$1"
|
||||
podman ps --filter "label=com.docker.compose.service=${service}" \
|
||||
--format '{{.Names}}' | head -1
|
||||
}
|
||||
|
||||
# ── 1. SQLite ──────────────────────────────────────────────────────────────────
|
||||
log "--- SQLite ---"
|
||||
SERVER_CTR=$(find_container server)
|
||||
if [ -n "${SERVER_CTR}" ]; then
|
||||
log "Copying hiy.db from container ${SERVER_CTR}…"
|
||||
podman cp "${SERVER_CTR}:${HIY_DATA_DIR}/hiy.db" "${STAGING}/hiy.db"
|
||||
log "Dumping hiy.db…"
|
||||
sqlite3 "${STAGING}/hiy.db" .dump > "${STAGING}/hiy.sql"
|
||||
rm "${STAGING}/hiy.db"
|
||||
elif [ -f "${HIY_DATA_DIR}/hiy.db" ]; then
|
||||
log "Server container not running — dumping from host path…"
|
||||
# SQLite: use the .dump command to produce a portable SQL text dump.
|
||||
if [ -f "${HIY_DATA_DIR}/hiy.db" ]; then
|
||||
log "Dumping SQLite database…"
|
||||
sqlite3 "${HIY_DATA_DIR}/hiy.db" .dump > "${STAGING}/hiy.sql"
|
||||
else
|
||||
log "WARNING: hiy.db not found — skipping SQLite dump"
|
||||
log "WARNING: ${HIY_DATA_DIR}/hiy.db not found — skipping SQLite dump"
|
||||
fi
|
||||
|
||||
# ── 2. Env files ───────────────────────────────────────────────────────────────
|
||||
log "--- Env files ---"
|
||||
if [ -n "${SERVER_CTR}" ]; then
|
||||
podman exec "${SERVER_CTR}" sh -c \
|
||||
"[ -d ${HIY_DATA_DIR}/envs ] && tar -C ${HIY_DATA_DIR} -czf - envs" \
|
||||
> "${STAGING}/envs.tar.gz" 2>/dev/null || true
|
||||
elif [ -d "${HIY_DATA_DIR}/envs" ]; then
|
||||
tar -czf "${STAGING}/envs.tar.gz" -C "${HIY_DATA_DIR}" envs
|
||||
# Env files (contain decrypted secrets — handle with care).
|
||||
if [ -d "${HIY_DATA_DIR}/envs" ]; then
|
||||
log "Copying env files…"
|
||||
cp -r "${HIY_DATA_DIR}/envs" "${STAGING}/envs"
|
||||
fi
|
||||
|
||||
# ── 3. Git repos ───────────────────────────────────────────────────────────────
|
||||
log "--- Git repos ---"
|
||||
if [ -n "${SERVER_CTR}" ]; then
|
||||
podman exec "${SERVER_CTR}" sh -c \
|
||||
"[ -d ${HIY_DATA_DIR}/repos ] && tar -C ${HIY_DATA_DIR} -czf - repos" \
|
||||
> "${STAGING}/repos.tar.gz" 2>/dev/null || true
|
||||
elif [ -d "${HIY_DATA_DIR}/repos" ]; then
|
||||
tar -czf "${STAGING}/repos.tar.gz" -C "${HIY_DATA_DIR}" repos
|
||||
# Bare git repos.
|
||||
if [ -d "${HIY_DATA_DIR}/repos" ]; then
|
||||
log "Copying git repos…"
|
||||
cp -r "${HIY_DATA_DIR}/repos" "${STAGING}/repos"
|
||||
fi
|
||||
|
||||
# ── 4. Postgres ────────────────────────────────────────────────────────────────
|
||||
log "--- Postgres ---"
|
||||
PG_CTR=$(find_container postgres)
|
||||
if [ -n "${PG_CTR}" ]; then
|
||||
log "Running pg_dumpall via container ${PG_CTR}…"
|
||||
podman exec "${PG_CTR}" pg_dumpall -U hiy_admin \
|
||||
> "${STAGING}/postgres.sql"
|
||||
else
|
||||
log "WARNING: postgres container not running — skipping Postgres dump"
|
||||
fi
|
||||
|
||||
# ── 5. Forgejo data volume ─────────────────────────────────────────────────────
|
||||
log "--- Forgejo volume ---"
|
||||
if podman volume exists forgejo-data 2>/dev/null; then
|
||||
log "Exporting forgejo-data volume…"
|
||||
podman volume export forgejo-data > "${STAGING}/forgejo-data.tar"
|
||||
else
|
||||
log "forgejo-data volume not found — skipping"
|
||||
fi
|
||||
|
||||
# ── 6. Caddy TLS certificates ──────────────────────────────────────────────────
|
||||
log "--- Caddy volume ---"
|
||||
if podman volume exists caddy-data 2>/dev/null; then
|
||||
log "Exporting caddy-data volume…"
|
||||
podman volume export caddy-data > "${STAGING}/caddy-data.tar"
|
||||
else
|
||||
log "caddy-data volume not found — skipping"
|
||||
fi
|
||||
|
||||
# ── 7. .env file ───────────────────────────────────────────────────────────────
|
||||
log "--- .env ---"
|
||||
if [ -f "${ENV_FILE}" ]; then
|
||||
cp "${ENV_FILE}" "${STAGING}/dot-env"
|
||||
log "WARNING: archive contains plaintext secrets — store it securely"
|
||||
else
|
||||
log ".env not found at ${ENV_FILE} — skipping"
|
||||
fi
|
||||
|
||||
# ── Create archive ─────────────────────────────────────────────────────────────
|
||||
# ── 2. Create archive ──────────────────────────────────────────────────────────
|
||||
mkdir -p "${BACKUP_DIR}"
|
||||
ARCHIVE_PATH="${BACKUP_DIR}/${ARCHIVE_NAME}"
|
||||
log "Creating archive: ${ARCHIVE_PATH}"
|
||||
|
|
@ -138,20 +67,19 @@ rm -rf "${STAGING}"
|
|||
ARCHIVE_SIZE=$(du -sh "${ARCHIVE_PATH}" | cut -f1)
|
||||
log "Archive size: ${ARCHIVE_SIZE}"
|
||||
|
||||
# ── Upload to remote (optional) ────────────────────────────────────────────────
|
||||
# ── 3. Upload to remote (optional) ────────────────────────────────────────────
|
||||
if [ -n "${BACKUP_REMOTE}" ]; then
|
||||
if command -v rclone &>/dev/null; then
|
||||
log "Uploading to ${BACKUP_REMOTE}…"
|
||||
#use patched rclone for now
|
||||
/home/sander/dev/rclone/rclone copy --transfers 1 --retries 5 "${ARCHIVE_PATH}" "${BACKUP_REMOTE}/"
|
||||
log "Uploading to remote: ${BACKUP_REMOTE}"
|
||||
rclone copy "${ARCHIVE_PATH}" "${BACKUP_REMOTE}/"
|
||||
log "Upload complete."
|
||||
else
|
||||
log "WARNING: HIY_BACKUP_REMOTE is set but rclone is not installed — skipping"
|
||||
log "Install: https://rclone.org/install/"
|
||||
log "WARNING: HIY_BACKUP_REMOTE is set but rclone is not installed — skipping upload"
|
||||
log "Install rclone: https://rclone.org/install/"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── Rotate old local backups ───────────────────────────────────────────────────
|
||||
# ── 4. Rotate old local backups ────────────────────────────────────────────────
|
||||
log "Removing local backups older than ${RETAIN_DAYS} days…"
|
||||
find "${BACKUP_DIR}" -maxdepth 1 -name 'hiy-backup-*.tar.gz' \
|
||||
-mtime "+${RETAIN_DAYS}" -delete
|
||||
|
|
|
|||
|
|
@ -93,8 +93,6 @@ services:
|
|||
FORGEJO__server__SSH_DOMAIN: ${FORGEJO_DOMAIN}
|
||||
# Skip the first-run wizard — everything is configured via env vars above.
|
||||
FORGEJO__security__INSTALL_LOCK: "true"
|
||||
# Enable Actions.
|
||||
FORGEJO__actions__ENABLED: "true"
|
||||
volumes:
|
||||
- forgejo-data:/data
|
||||
depends_on:
|
||||
|
|
@ -102,28 +100,6 @@ services:
|
|||
networks:
|
||||
- hiy-net
|
||||
|
||||
# ── Forgejo Actions runner ─────────────────────────────────────────────────
|
||||
# Obtain FORGEJO_RUNNER_TOKEN from Forgejo:
|
||||
# Site Administration → Actions → Runners → Create new runner
|
||||
act_runner:
|
||||
image: data.forgejo.org/forgejo/runner:6
|
||||
restart: unless-stopped
|
||||
command: ["/entrypoint.sh"]
|
||||
environment:
|
||||
FORGEJO_INSTANCE_URL: http://forgejo:3000
|
||||
FORGEJO_RUNNER_TOKEN: ${FORGEJO_RUNNER_TOKEN}
|
||||
FORGEJO_RUNNER_NAME: hiy-runner
|
||||
# Give the runner access to Podman so CI jobs can build/run containers.
|
||||
DOCKER_HOST: tcp://podman-proxy:2375
|
||||
volumes:
|
||||
- act_runner_data:/data
|
||||
- ./runner-entrypoint.sh:/entrypoint.sh:ro
|
||||
depends_on:
|
||||
- forgejo
|
||||
- podman-proxy
|
||||
networks:
|
||||
- hiy-net
|
||||
|
||||
# ── Reverse proxy ─────────────────────────────────────────────────────────
|
||||
caddy:
|
||||
image: docker.io/library/caddy:2-alpine
|
||||
|
|
@ -194,7 +170,6 @@ networks:
|
|||
volumes:
|
||||
hiy-data:
|
||||
forgejo-data:
|
||||
act_runner_data:
|
||||
caddy-data:
|
||||
caddy-config:
|
||||
hiy-pg-data:
|
||||
|
|
|
|||
142
infra/install.sh
142
infra/install.sh
|
|
@ -1,142 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# install.sh — one-time setup for a fresh Raspberry Pi.
|
||||
#
|
||||
# Run this once after cloning the repo:
|
||||
# cd ~/Hostityourself && ./infra/install.sh
|
||||
#
|
||||
# What it does:
|
||||
# 1. Installs system packages (podman, aardvark-dns, sqlite3, git, uidmap)
|
||||
# 2. Installs podman-compose (via pip, into ~/.local/bin)
|
||||
# 3. Installs rclone (for off-site backups — optional)
|
||||
# 4. Creates .env from the template and prompts for required values
|
||||
# 5. Runs infra/start.sh to build and launch the stack
|
||||
#
|
||||
# Safe to re-run — all steps are idempotent.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
log() { echo; echo "▶ $*"; }
|
||||
info() { echo " $*"; }
|
||||
ok() { echo " ✓ $*"; }
|
||||
|
||||
echo "╔══════════════════════════════════════════╗"
|
||||
echo "║ HostItYourself — installer ║"
|
||||
echo "╚══════════════════════════════════════════╝"
|
||||
|
||||
# ── 1. System packages ─────────────────────────────────────────────────────────
|
||||
log "Installing system packages…"
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y \
|
||||
podman \
|
||||
aardvark-dns \
|
||||
sqlite3 \
|
||||
git \
|
||||
uidmap \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
curl
|
||||
ok "System packages installed."
|
||||
|
||||
# ── 2. podman-compose ──────────────────────────────────────────────────────────
|
||||
log "Checking podman-compose…"
|
||||
if command -v podman-compose &>/dev/null; then
|
||||
ok "podman-compose already installed ($(podman-compose --version 2>&1 | head -1))."
|
||||
else
|
||||
info "Installing podman-compose via pip…"
|
||||
pip3 install --user podman-compose
|
||||
ok "podman-compose installed to ~/.local/bin"
|
||||
fi
|
||||
|
||||
# Ensure ~/.local/bin is in PATH for this session and future logins.
|
||||
if ! echo "$PATH" | grep -q "$HOME/.local/bin"; then
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
fi
|
||||
PROFILE="$HOME/.bashrc"
|
||||
if ! grep -q '\.local/bin' "$PROFILE" 2>/dev/null; then
|
||||
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$PROFILE"
|
||||
info "Added ~/.local/bin to PATH in $PROFILE"
|
||||
fi
|
||||
|
||||
# ── 3. rclone (optional) ───────────────────────────────────────────────────────
|
||||
log "rclone (used for off-site backups)…"
|
||||
if command -v rclone &>/dev/null; then
|
||||
ok "rclone already installed ($(rclone --version 2>&1 | head -1))."
|
||||
else
|
||||
read -r -p " Install rclone? [y/N] " _RCLONE
|
||||
if [[ "${_RCLONE,,}" == "y" ]]; then
|
||||
curl -fsSL https://rclone.org/install.sh | sudo bash
|
||||
ok "rclone installed."
|
||||
info "Configure a remote later with: rclone config"
|
||||
info "Then set HIY_BACKUP_REMOTE in .env"
|
||||
else
|
||||
info "Skipped. Install later with: curl https://rclone.org/install.sh | sudo bash"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ── 4. .env setup ──────────────────────────────────────────────────────────────
|
||||
log "Setting up .env…"
|
||||
ENV_FILE="$REPO_ROOT/.env"
|
||||
ENV_EXAMPLE="$SCRIPT_DIR/.env.example"
|
||||
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
ok ".env already exists — skipping (edit manually if needed)."
|
||||
else
|
||||
cp "$ENV_EXAMPLE" "$ENV_FILE"
|
||||
info "Created .env from template. Filling in required values…"
|
||||
echo
|
||||
|
||||
# Helper: prompt for a value and write it into .env.
|
||||
set_env() {
|
||||
local key="$1" prompt="$2" default="$3" secret="${4:-}"
|
||||
local current
|
||||
current=$(grep "^${key}=" "$ENV_FILE" | cut -d= -f2- || echo "")
|
||||
if [ -z "$current" ] || [ "$current" = "changeme" ] || [ "$current" = "" ]; then
|
||||
if [ -n "$secret" ]; then
|
||||
read -r -s -p " ${prompt} [${default}]: " _VAL; echo
|
||||
else
|
||||
read -r -p " ${prompt} [${default}]: " _VAL
|
||||
fi
|
||||
_VAL="${_VAL:-$default}"
|
||||
# Replace the line in .env (works on both macOS and Linux).
|
||||
sed -i "s|^${key}=.*|${key}=${_VAL}|" "$ENV_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
set_env "DOMAIN_SUFFIX" "Your domain (e.g. example.com)" "yourdomain.com"
|
||||
set_env "ACME_EMAIL" "Email for Let's Encrypt notices" ""
|
||||
set_env "HIY_ADMIN_USER" "Dashboard admin username" "admin"
|
||||
set_env "HIY_ADMIN_PASS" "Dashboard admin password" "$(openssl rand -hex 12)" "secret"
|
||||
set_env "POSTGRES_PASSWORD" "Postgres admin password" "$(openssl rand -hex 16)" "secret"
|
||||
set_env "FORGEJO_DB_PASSWORD" "Forgejo DB password" "$(openssl rand -hex 16)" "secret"
|
||||
set_env "FORGEJO_DOMAIN" "Forgejo domain (e.g. git.example.com)" "git.yourdomain.com"
|
||||
|
||||
echo
|
||||
ok ".env written to $ENV_FILE"
|
||||
info "Review it with: cat $ENV_FILE"
|
||||
fi
|
||||
|
||||
# ── 5. Git remote check ────────────────────────────────────────────────────────
|
||||
log "Checking git remote…"
|
||||
cd "$REPO_ROOT"
|
||||
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
|
||||
if [ -n "$REMOTE_URL" ]; then
|
||||
ok "Git remote: $REMOTE_URL"
|
||||
else
|
||||
info "No git remote configured — auto-update will not work."
|
||||
info "Set one with: git remote add origin <url>"
|
||||
fi
|
||||
|
||||
# Ensure the tracking branch is set so auto-update.sh can compare commits.
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
if ! git rev-parse --abbrev-ref --symbolic-full-name '@{u}' &>/dev/null; then
|
||||
info "Setting upstream tracking branch…"
|
||||
git branch --set-upstream-to="origin/$BRANCH" "$BRANCH" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# ── 6. Launch the stack ────────────────────────────────────────────────────────
|
||||
log "Running start.sh to build and launch the stack…"
|
||||
echo
|
||||
exec "$SCRIPT_DIR/start.sh"
|
||||
143
infra/restore.sh
143
infra/restore.sh
|
|
@ -1,143 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# HIY restore script
|
||||
#
|
||||
# Restores a backup archive produced by infra/backup.sh.
|
||||
#
|
||||
# Usage:
|
||||
# ./infra/restore.sh /path/to/hiy-backup-20260101-030000.tar.gz
|
||||
#
|
||||
# What is restored:
|
||||
# 1. SQLite database (hiy.db)
|
||||
# 2. Env files and git repos
|
||||
# 3. Postgres databases (pg_dumpall dump)
|
||||
# 4. Forgejo data volume
|
||||
# 5. Caddy TLS certificates
|
||||
# 6. .env file (optional — skipped if already present unless --force is passed)
|
||||
#
|
||||
# ⚠ Run this with the stack STOPPED, then bring it back up afterwards:
|
||||
# podman compose -f infra/docker-compose.yml down
|
||||
# ./infra/restore.sh hiy-backup-*.tar.gz
|
||||
# podman compose -f infra/docker-compose.yml up -d
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ARCHIVE="${1:-}"
|
||||
FORCE="${2:-}"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ENV_FILE="${SCRIPT_DIR}/../.env"
|
||||
HIY_DATA_DIR="${HIY_DATA_DIR:-/data}"
|
||||
|
||||
log() { echo "[hiy-restore] $(date '+%H:%M:%S') $*"; }
|
||||
die() { log "ERROR: $*"; exit 1; }
|
||||
|
||||
# ── Validate ───────────────────────────────────────────────────────────────────
|
||||
[ -z "${ARCHIVE}" ] && die "Usage: $0 <archive.tar.gz> [--force]"
|
||||
[ -f "${ARCHIVE}" ] || die "Archive not found: ${ARCHIVE}"
|
||||
|
||||
WORK_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "${WORK_DIR}"' EXIT
|
||||
|
||||
log "=== HIY Restore ==="
|
||||
log "Archive : ${ARCHIVE}"
|
||||
log "Work dir: ${WORK_DIR}"
|
||||
|
||||
log "Extracting archive…"
|
||||
tar -xzf "${ARCHIVE}" -C "${WORK_DIR}"
|
||||
|
||||
# ── Helper: find a running container by compose service label ──────────────────
|
||||
find_container() {
|
||||
local service="$1"
|
||||
podman ps --filter "label=com.docker.compose.service=${service}" \
|
||||
--format '{{.Names}}' | head -1
|
||||
}
|
||||
|
||||
# ── 1. .env file ───────────────────────────────────────────────────────────────
|
||||
log "--- .env ---"
|
||||
if [ -f "${WORK_DIR}/dot-env" ]; then
|
||||
if [ -f "${ENV_FILE}" ] && [ "${FORCE}" != "--force" ]; then
|
||||
log "SKIP: ${ENV_FILE} already exists (pass --force to overwrite)"
|
||||
else
|
||||
cp "${WORK_DIR}/dot-env" "${ENV_FILE}"
|
||||
log "Restored .env to ${ENV_FILE}"
|
||||
fi
|
||||
else
|
||||
log "No .env in archive — skipping"
|
||||
fi
|
||||
|
||||
# ── 2. SQLite ──────────────────────────────────────────────────────────────────
|
||||
log "--- SQLite ---"
|
||||
if [ -f "${WORK_DIR}/hiy.sql" ]; then
|
||||
DB_PATH="${HIY_DATA_DIR}/hiy.db"
|
||||
mkdir -p "$(dirname "${DB_PATH}")"
|
||||
if [ -f "${DB_PATH}" ]; then
|
||||
log "Moving existing hiy.db to hiy.db.bak…"
|
||||
mv "${DB_PATH}" "${DB_PATH}.bak"
|
||||
fi
|
||||
log "Restoring hiy.db…"
|
||||
sqlite3 "${DB_PATH}" < "${WORK_DIR}/hiy.sql"
|
||||
log "SQLite restored."
|
||||
else
|
||||
log "No hiy.sql in archive — skipping"
|
||||
fi
|
||||
|
||||
# ── 3. Env files & git repos ───────────────────────────────────────────────────
|
||||
log "--- Env files ---"
|
||||
if [ -f "${WORK_DIR}/envs.tar.gz" ]; then
|
||||
log "Restoring envs/…"
|
||||
tar -xzf "${WORK_DIR}/envs.tar.gz" -C "${HIY_DATA_DIR}"
|
||||
fi
|
||||
|
||||
log "--- Git repos ---"
|
||||
if [ -f "${WORK_DIR}/repos.tar.gz" ]; then
|
||||
log "Restoring repos/…"
|
||||
tar -xzf "${WORK_DIR}/repos.tar.gz" -C "${HIY_DATA_DIR}"
|
||||
fi
|
||||
|
||||
# ── 4. Postgres ────────────────────────────────────────────────────────────────
|
||||
log "--- Postgres ---"
|
||||
if [ -f "${WORK_DIR}/postgres.sql" ]; then
|
||||
PG_CTR=$(find_container postgres)
|
||||
if [ -n "${PG_CTR}" ]; then
|
||||
log "Restoring Postgres via container ${PG_CTR}…"
|
||||
# Drop existing connections then restore.
|
||||
podman exec -i "${PG_CTR}" psql -U hiy_admin -d postgres \
|
||||
-c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IN ('hiy','forgejo') AND pid <> pg_backend_pid();" \
|
||||
> /dev/null 2>&1 || true
|
||||
podman exec -i "${PG_CTR}" psql -U hiy_admin -d postgres \
|
||||
< "${WORK_DIR}/postgres.sql"
|
||||
log "Postgres restored."
|
||||
else
|
||||
log "WARNING: postgres container not running"
|
||||
log " Start Postgres first, then run:"
|
||||
log " podman exec -i <postgres_container> psql -U hiy_admin -d postgres < ${WORK_DIR}/postgres.sql"
|
||||
fi
|
||||
else
|
||||
log "No postgres.sql in archive — skipping"
|
||||
fi
|
||||
|
||||
# ── 5. Forgejo data volume ─────────────────────────────────────────────────────
|
||||
log "--- Forgejo volume ---"
|
||||
if [ -f "${WORK_DIR}/forgejo-data.tar" ]; then
|
||||
log "Importing forgejo-data volume…"
|
||||
podman volume exists forgejo-data 2>/dev/null || podman volume create forgejo-data
|
||||
podman volume import forgejo-data "${WORK_DIR}/forgejo-data.tar"
|
||||
log "forgejo-data restored."
|
||||
else
|
||||
log "No forgejo-data.tar in archive — skipping"
|
||||
fi
|
||||
|
||||
# ── 6. Caddy TLS certificates ──────────────────────────────────────────────────
|
||||
log "--- Caddy volume ---"
|
||||
if [ -f "${WORK_DIR}/caddy-data.tar" ]; then
|
||||
log "Importing caddy-data volume…"
|
||||
podman volume exists caddy-data 2>/dev/null || podman volume create caddy-data
|
||||
podman volume import caddy-data "${WORK_DIR}/caddy-data.tar"
|
||||
log "caddy-data restored."
|
||||
else
|
||||
log "No caddy-data.tar in archive — skipping"
|
||||
fi
|
||||
|
||||
log "=== Restore complete ==="
|
||||
log "Bring the stack back up with:"
|
||||
log " podman compose -f ${SCRIPT_DIR}/docker-compose.yml up -d"
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#!/bin/sh
|
||||
# runner-entrypoint.sh — register the Forgejo runner on first start, then run the daemon.
|
||||
#
|
||||
# On first run (no /data/.runner file) it calls create-runner-file to register
|
||||
# with the Forgejo instance using FORGEJO_RUNNER_TOKEN. On subsequent starts it
|
||||
# goes straight to the daemon.
|
||||
set -e
|
||||
|
||||
CONFIG=/data/.runner
|
||||
|
||||
if [ ! -f "$CONFIG" ]; then
|
||||
echo "[runner] No registration found — registering with Forgejo…"
|
||||
forgejo-runner register \
|
||||
--instance "${FORGEJO_INSTANCE_URL}" \
|
||||
--token "${FORGEJO_RUNNER_TOKEN}" \
|
||||
--name "${FORGEJO_RUNNER_NAME:-hiy-runner}" \
|
||||
--labels "ubuntu-latest:docker://node:20-bookworm,ubuntu-22.04:docker://node:20-bookworm" \
|
||||
--no-interactive
|
||||
echo "[runner] Registration complete."
|
||||
fi
|
||||
|
||||
echo "[runner] Starting daemon…"
|
||||
exec forgejo-runner daemon --config "$CONFIG"
|
||||
|
|
@ -171,7 +171,6 @@ Wants=network-online.target
|
|||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/$(id -un)/.local/bin
|
||||
ExecStart=${SCRIPT_DIR}/boot.sh
|
||||
ExecStop=podman compose --env-file ${REPO_ROOT}/.env -f ${SCRIPT_DIR}/docker-compose.yml down
|
||||
|
||||
|
|
@ -183,37 +182,3 @@ systemctl --user daemon-reload
|
|||
systemctl --user enable hiy.service
|
||||
loginctl enable-linger "$(id -un)" 2>/dev/null || true
|
||||
echo "[hiy] Boot service installed: systemctl --user status hiy.service"
|
||||
|
||||
# ── Install systemd timer for auto-update ─────────────────────────────────────
|
||||
UPDATE_SERVICE="$SERVICE_DIR/hiy-update.service"
|
||||
UPDATE_TIMER="$SERVICE_DIR/hiy-update.timer"
|
||||
|
||||
cat > "$UPDATE_SERVICE" <<UNIT
|
||||
[Unit]
|
||||
Description=HIY auto-update (git pull + restart changed services)
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/$(id -un)/.local/bin
|
||||
ExecStart=${SCRIPT_DIR}/auto-update.sh
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
UNIT
|
||||
|
||||
cat > "$UPDATE_TIMER" <<UNIT
|
||||
[Unit]
|
||||
Description=HIY auto-update every 5 minutes
|
||||
|
||||
[Timer]
|
||||
OnBootSec=2min
|
||||
OnUnitActiveSec=5min
|
||||
Unit=hiy-update.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
UNIT
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now hiy-update.timer
|
||||
echo "[hiy] Auto-update timer installed: systemctl --user status hiy-update.timer"
|
||||
|
|
|
|||
|
|
@ -162,12 +162,6 @@ async fn main() -> anyhow::Result<()> {
|
|||
routes::apps::restore_caddy_routes(&restore_db).await;
|
||||
});
|
||||
|
||||
// Restart any app containers that are stopped (e.g. after a host reboot).
|
||||
let containers_db = state.db.clone();
|
||||
tokio::spawn(async move {
|
||||
routes::apps::restore_app_containers(&containers_db).await;
|
||||
});
|
||||
|
||||
// ── Protected routes (admin login required) ───────────────────────────────
|
||||
let protected = Router::new()
|
||||
.route("/", get(routes::ui::index))
|
||||
|
|
|
|||
|
|
@ -76,73 +76,6 @@ pub async fn restore_caddy_routes(db: &crate::DbPool) {
|
|||
tracing::info!("restore_caddy_routes: registered {} app routes", apps.len());
|
||||
}
|
||||
|
||||
/// On startup, ensure every app that had a successful deploy is actually running.
|
||||
/// If the host rebooted, containers will be in "exited" state — start them.
|
||||
/// If a container is missing entirely, log a warning (we don't rebuild automatically).
|
||||
pub async fn restore_app_containers(db: &crate::DbPool) {
|
||||
let apps = match sqlx::query_as::<_, crate::models::App>("SELECT * FROM apps")
|
||||
.fetch_all(db)
|
||||
.await
|
||||
{
|
||||
Ok(a) => a,
|
||||
Err(e) => { tracing::error!("restore_app_containers: DB error: {}", e); return; }
|
||||
};
|
||||
|
||||
for app in &apps {
|
||||
// Only care about apps that have at least one successful deploy.
|
||||
let has_deploy: bool = sqlx::query_scalar(
|
||||
"SELECT COUNT(*) > 0 FROM deploys WHERE app_id = ? AND status = 'success'"
|
||||
)
|
||||
.bind(&app.id)
|
||||
.fetch_one(db)
|
||||
.await
|
||||
.unwrap_or(false);
|
||||
|
||||
if !has_deploy {
|
||||
continue;
|
||||
}
|
||||
|
||||
let container = format!("hiy-{}", app.id);
|
||||
|
||||
// Check container state via `podman inspect`.
|
||||
let inspect = tokio::process::Command::new("podman")
|
||||
.args(["inspect", "--format", "{{.State.Status}}", &container])
|
||||
.output()
|
||||
.await;
|
||||
|
||||
match inspect {
|
||||
Ok(out) if out.status.success() => {
|
||||
let status = String::from_utf8_lossy(&out.stdout).trim().to_string();
|
||||
if status == "running" {
|
||||
tracing::debug!("restore_app_containers: {} already running", container);
|
||||
} else {
|
||||
tracing::info!("restore_app_containers: starting {} (was {})", container, status);
|
||||
let start = tokio::process::Command::new("podman")
|
||||
.args(["start", &container])
|
||||
.output()
|
||||
.await;
|
||||
match start {
|
||||
Ok(o) if o.status.success() =>
|
||||
tracing::info!("restore_app_containers: {} started", container),
|
||||
Ok(o) =>
|
||||
tracing::warn!("restore_app_containers: failed to start {}: {}",
|
||||
container, String::from_utf8_lossy(&o.stderr).trim()),
|
||||
Err(e) =>
|
||||
tracing::warn!("restore_app_containers: error starting {}: {}", container, e),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
tracing::warn!(
|
||||
"restore_app_containers: container {} not found — redeploy needed",
|
||||
container
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
tracing::info!("restore_app_containers: done");
|
||||
}
|
||||
|
||||
/// Push a visibility change to Caddy without requiring a full redeploy.
|
||||
/// Best-effort: logs a warning on failure but does not surface an error to the caller.
|
||||
async fn push_visibility_to_caddy(app_id: &str, port: i64, is_public: bool) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue