diff --git a/.forgejo/workflows/docker.yaml b/.forgejo/workflows/docker.yaml index a8c493d..4c8b3b2 100644 --- a/.forgejo/workflows/docker.yaml +++ b/.forgejo/workflows/docker.yaml @@ -4,7 +4,6 @@ on: push: branches: ["main"] paths: - - "Cargo.toml" - ".forgejo/workflows/docker.yaml" - "nix/image/**" @@ -17,9 +16,10 @@ jobs: strategy: 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 }} + name: haze-${{ matrix.php-version }}${{ matrix.variant }} steps: - name: Checkout repository diff --git a/Cargo.lock b/Cargo.lock index 821ff04..aba8178 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,7 +25,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures", ] [[package]] @@ -147,7 +147,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" dependencies = [ "axum-core", - "axum-macros", "bytes", "form_urlencoded", "futures-util", @@ -193,17 +192,6 @@ dependencies = [ "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]] name = "backtrace" version = "0.3.74" @@ -266,9 +254,9 @@ dependencies = [ [[package]] name = "bollard" -version = "0.21.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d0a013e3d3ee4edd61e779adf117944c08902d375f18630a0c5b8f95659734" +checksum = "227aa051deec8d16bd9c34605e7aaf153f240e35483dd42f6f78903847934738" dependencies = [ "base64", "bollard-stubs", @@ -298,9 +286,9 @@ dependencies = [ [[package]] name = "bollard-stubs" -version = "1.53.1-rc.29.3.1" +version = "1.52.1-rc.29.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce412eb6f7096743011dc3cb5c674caeb24ced61d8c498fe07cf7998a4fea889" +checksum = "0f0a8ca8799131c1837d1282c3f81f31e76ceb0ce426e04a7fe1ccee3287c066" dependencies = [ "serde", "serde_json", @@ -384,17 +372,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "cipher" version = "0.4.4" @@ -520,15 +497,6 @@ dependencies = [ "libc", ] -[[package]] -name = "cpufeatures" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" -dependencies = [ - "libc", -] - [[package]] name = "crc32fast" version = "1.5.0" @@ -538,31 +506,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - [[package]] name = "crypto-common" version = "0.1.7" @@ -917,7 +860,6 @@ dependencies = [ "js-sys", "libc", "r-efi", - "rand_core 0.10.1", "wasip2", "wasip3", "wasm-bindgen", @@ -943,14 +885,34 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "git2" -version = "0.21.0" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddddbf932745a6be37109b6112d3ee09696106f848449069d3a57bba937ab82e" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" dependencies = [ "bitflags", "libc", "libgit2-sys", "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]] @@ -970,7 +932,7 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "haze" -version = "2.3.0" +version = "2.2.0" dependencies = [ "async-trait", "atty", @@ -994,7 +956,6 @@ dependencies = [ "opener", "owo-colors", "petname", - "rayon", "reqwest", "serde", "serde_json", @@ -1004,7 +965,6 @@ dependencies = [ "tar", "termion", "tokio", - "tokio-stream", "toml", "tracing", "tracing-subscriber", @@ -1112,6 +1072,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", + "h2", "http", "http-body", "httparse", @@ -1142,9 +1103,8 @@ dependencies = [ [[package]] name = "hyper-reverse-proxy" version = "0.5.2-dev" -source = "git+https://code.betamike.com/micropelago/hyper-reverse-proxy.git?rev=d5a6f799189360d9449ae47ab3cdde511f02cf39#d5a6f799189360d9449ae47ab3cdde511f02cf39" +source = "git+https://github.com/chpio/hyper-reverse-proxy?rev=6934877eb74465204f605cc1c05ca5a9772db7c0#6934877eb74465204f605cc1c05ca5a9772db7c0" dependencies = [ - "http-body-util", "hyper", "hyper-util", "tokio", @@ -1511,9 +1471,9 @@ checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] name = "libgit2-sys" -version = "0.18.5+1.9.4" +version = "0.18.3+1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005d6ae6eac1912906073e069f7db60b1fa98e052a68227824afe3e3a1c59ca2" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" dependencies = [ "cc", "libc", @@ -1814,24 +1774,16 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petname" -version = "3.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce610bff48dd7b6a127e45631795fbb0b302b99a39bef7e6da3d297e8eb2b6b" +checksum = "9cd31dcfdbbd7431a807ef4df6edd6473228e94d5c805e8cf671227a21bad068" dependencies = [ + "anyhow", "clap", - "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 = [ + "itertools", "proc-macro2", "quote", - "syn", + "rand 0.8.5", ] [[package]] @@ -1993,23 +1945,33 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.9.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "rand_chacha", - "rand_core 0.9.5", + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.10.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "chacha20", - "getrandom 0.4.1", - "rand_core 0.10.1", + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] @@ -2022,6 +1984,15 @@ dependencies = [ "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]] name = "rand_core" version = "0.9.5" @@ -2031,32 +2002,6 @@ dependencies = [ "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]] name = "redox_syscall" version = "0.5.10" @@ -2389,7 +2334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest 0.10.7", ] @@ -2400,7 +2345,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest 0.10.7", ] @@ -2411,7 +2356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest 0.11.1", ] @@ -2750,17 +2695,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-stream" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.13" diff --git a/Cargo.toml b/Cargo.toml index 631f10f..73a4c8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "haze" -version = "2.3.0" +version = "2.2.0" authors = ["Robin Appelman "] edition = "2021" repository = "https://codeberg.org/icewind/haze" @@ -8,11 +8,10 @@ license = "MIT" description = "Easy setup and management of Nextcloud test instances using docker" [dependencies] -bollard = "0.21.0" +bollard = "0.20.1" maplit = "1.0.2" camino = { version = "1.2.2", features = ["serde1"] } 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" termion = "4.0.6" opener = "0.8.4" @@ -20,7 +19,7 @@ toml = "1.0.3" directories-next = "2.0.0" serde = "1.0.228" serde_json = "1.0.149" -petname = "3.0.0" +petname = "2.0.2" reqwest = { version = "0.13.2", default-features = false, features = ["rustls"] } tar = "0.4.44" flate2 = "1.1.9" @@ -31,7 +30,7 @@ shell-words = "1.1.1" tracing = "0.1.44" tracing-subscriber = "0.3.22" atty = "0.2.14" -git2 = { version = "0.21.0", default-features = false } +git2 = { version = "0.20.4", default-features = false } itertools = { version = "0.14.0", features = ["use_alloc"] } local-ip-address = "0.6.10" strum = { version = "0.28.0", features = ["derive"] } @@ -40,12 +39,11 @@ zip = "8.1.0" sha2 = "0.11.0-rc.5" base16ct = { version = "1.0.0", features = ["alloc"] } indicatif = "0.18.4" -rayon = "1.12.0" -hyper-reverse-proxy = { version = "0.5.2-dev", git = "https://code.betamike.com/micropelago/hyper-reverse-proxy.git", rev = "d5a6f799189360d9449ae47ab3cdde511f02cf39" } +hyper-reverse-proxy = { version = "0.5.2-dev", git = "https://github.com/chpio/hyper-reverse-proxy", rev = "6934877eb74465204f605cc1c05ca5a9772db7c0" } hyper = "1.8.1" hyper-util = "0.1.20" -axum = { version = "0.8.8", features = ["tokio", "macros"] } +axum = { version = "0.8.8", features = ["tokio"] } [profile.release] lto = true diff --git a/README.md b/README.md index aa538d2..839e91c 100644 --- a/README.md +++ b/README.md @@ -81,8 +81,6 @@ Additionally, you can use the following options when starting an instance: - `smb`: set up a samba 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-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 [manually setting up the image](https://github.com/icewind1991/kaspersky-docker)) - `kaspersky-icap`: setup a kaspersky scan engine server in ICAP mode. @@ -95,8 +93,6 @@ Additionally, you can use the following options when starting an instance: generation. - `mail`: start a [smtp4dev](https://github.com/rnwood/smtp4dev) server and configure it the mail server. -- `webhook` start a - [webhook tester](https://github.com/tarampampam/webhook-tester) - `redis`: start a separate container for redis. - `redis-tls`: connect to redis over TLS. - ``: by specifying the path to an app package this package @@ -151,14 +147,11 @@ haze [match] db #### Execute a command on an instance ```bash -haze [match] [service] [cmd] +haze [match] exec [cmd] ``` 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 ```bash @@ -281,7 +274,8 @@ proxy to allow using a wildcard domain. ### Setup - Set a DNS record for `*.haze.exmaple.com` and `haze.example.com` pointing to - your development machine. + your development machine. Pointing it to `127.0.0.1` will also work, but comes + with limitations like federation not being supported. - 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 systemd user service is recommended (see [haze.service](./haze.service) for an @@ -302,7 +296,7 @@ will automatically point to the last created instance. Additionally, the proxy allows access to the server containers trough either `-.haze.example.com` for a specific instance, or -`.haze.example.com` for the last created instance. For example +`.haze.example.com` for the last created instead. For example `rolling-bees-mail.haze.example.com` will give access to the smtp4dev web interface of the `rolling-bees` instance. diff --git a/certificates/sftp/id_rsa b/certificates/sftp/id_rsa deleted file mode 100644 index c8dcc4d..0000000 --- a/certificates/sftp/id_rsa +++ /dev/null @@ -1,38 +0,0 @@ ------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----- diff --git a/certificates/sftp/id_rsa.pub b/certificates/sftp/id_rsa.pub deleted file mode 100644 index 81a5db6..0000000 --- a/certificates/sftp/id_rsa.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDfbdpaofpjBEtsIE73hQo6R+cnabpmyJzR0y3dOYOeMtTQnOk63vC3n6YxmsQpBOl5+jPJQejfP4eSaWUsAY66k3LcD6MbY73nlRSDDR0Z+7qPo45vroO72Omq3wFDqCvdwRgBKmU8jsHzz39xWknmXUeIFSDJHtnXq/XmoIO2akVUgQIB0gISY+ix+Zm623dhiX3EtrLlYKZTO1ZL9qY9wazQM4QatZ4K13EYpZPdPLB0ErJDQ9t1gxqaAMhPslXVlLNk9qXLiwHsT52lLkCAEVVeZnrXXnUo3VMnyDKhSMWFjty1gQimdxmbJPg9i/Ii/FGxsm28RGJ40fwOhfkPC2pzFuAcrQ7Bi12XjJ1FdOhijeX6oiJ1/6DwANV5r+ZuR9M96B1Oijcs65OFc7ATEOW6SkzyhsUOnPViXUvqtEkBU07UqYdaGfq2jbeO1iMGFzMDaeR6ZBdBtVKNz+Ei2NAMgU0w6wtbfc/5jaT0uSkjRMvT2iA7E4VnMZmna00= haze@haze diff --git a/nix/image/bootstrap b/nix/image/bootstrap deleted file mode 100755 index 2c9dcff..0000000 --- a/nix/image/bootstrap +++ /dev/null @@ -1,88 +0,0 @@ -#!/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 diff --git a/nix/image/bootstrap.sh b/nix/image/bootstrap.sh new file mode 100755 index 0000000..a00a950 --- /dev/null +++ b/nix/image/bootstrap.sh @@ -0,0 +1,79 @@ +#!/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 \ No newline at end of file diff --git a/nix/image/configs.nix b/nix/image/configs.nix index afa06c7..1b90bc8 100644 --- a/nix/image/configs.nix +++ b/nix/image/configs.nix @@ -1,7 +1,12 @@ {runCommand}: runCommand "configs" {} '' - mkdir -p $out - cp -r ${./configs} $out/etc - chmod -R +w $out/etc - mkdir $out/etc/supervisor/enabled/ + mkdir -p $out/etc + mkdir -p $out/etc/sudoers.d + mkdir -p $out/conf + cp ${./configs/cron.conf} $out/etc/oc-cron.conf + 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 '' diff --git a/nix/image/configs/oc-cron.conf b/nix/image/configs/cron.conf similarity index 100% rename from nix/image/configs/oc-cron.conf rename to nix/image/configs/cron.conf diff --git a/nix/image/configs/dnsmasq.conf b/nix/image/configs/dnsmasq.conf deleted file mode 100644 index 2b1afc5..0000000 --- a/nix/image/configs/dnsmasq.conf +++ /dev/null @@ -1,6 +0,0 @@ -listen-address=127.0.0.22 -no-resolv - -address=/PROXY_BASE/HOST_IP - -server=UPSTREAM_DNS \ No newline at end of file diff --git a/nix/image/configs/home/.sqliterc b/nix/image/configs/home/.sqliterc deleted file mode 100644 index 0d5fe04..0000000 --- a/nix/image/configs/home/.sqliterc +++ /dev/null @@ -1 +0,0 @@ -.mode table diff --git a/nix/image/configs/nc/redis-default.php b/nix/image/configs/nc/redis-default.php index 71b18a8..2ba24aa 100644 --- a/nix/image/configs/nc/redis-default.php +++ b/nix/image/configs/nc/redis-default.php @@ -1 +1,2 @@ 'redis' => ['host' => 'localhost'], +//PLACEHOLDER diff --git a/nix/image/configs/nc/redis-tls.php b/nix/image/configs/nc/redis-tls.php index c3b9abe..cb454ac 100644 --- a/nix/image/configs/nc/redis-tls.php +++ b/nix/image/configs/nc/redis-tls.php @@ -8,3 +8,4 @@ 'verify_peer_name' => false, ], ], +//PLACEHOLDER diff --git a/nix/image/configs/sudoers.d/haze b/nix/image/configs/sudoers similarity index 100% rename from nix/image/configs/sudoers.d/haze rename to nix/image/configs/sudoers diff --git a/nix/image/configs/supervisor/blackfire.conf b/nix/image/configs/supervisor/blackfire.conf deleted file mode 100644 index ca6cd89..0000000 --- a/nix/image/configs/supervisor/blackfire.conf +++ /dev/null @@ -1,2 +0,0 @@ -[program:blackfire] -command = blackfire agent \ No newline at end of file diff --git a/nix/image/configs/supervisor/dnsmasq.conf b/nix/image/configs/supervisor/dnsmasq.conf deleted file mode 100644 index d57ed09..0000000 --- a/nix/image/configs/supervisor/dnsmasq.conf +++ /dev/null @@ -1,2 +0,0 @@ -[program:dnsmasq] -command = /bin/dnsmasq --keep-in-foreground -u root \ No newline at end of file diff --git a/nix/image/configs/supervisor/frankenphp.conf b/nix/image/configs/supervisor/frankenphp.conf deleted file mode 100644 index 8c1b1e5..0000000 --- a/nix/image/configs/supervisor/frankenphp.conf +++ /dev/null @@ -1,3 +0,0 @@ -[program:frankenphp] -command = /bin/frankenphp php-server -directory = /var/www/html \ No newline at end of file diff --git a/nix/image/configs/supervisor/nginx.conf b/nix/image/configs/supervisor/nginx.conf deleted file mode 100644 index 957e4b3..0000000 --- a/nix/image/configs/supervisor/nginx.conf +++ /dev/null @@ -1,2 +0,0 @@ -[program:nginx] -command = /bin/nginx -c /etc/nginx.conf diff --git a/nix/image/configs/supervisor/php-fpm.conf b/nix/image/configs/supervisor/php-fpm.conf deleted file mode 100644 index 69418c7..0000000 --- a/nix/image/configs/supervisor/php-fpm.conf +++ /dev/null @@ -1,2 +0,0 @@ -[program:php-fpm] -command = /bin/php-fpm --fpm-config /etc/php-fpm.conf diff --git a/nix/image/configs/supervisor/redis-plain.conf b/nix/image/configs/supervisor/redis-plain.conf deleted file mode 100644 index e9284cc..0000000 --- a/nix/image/configs/supervisor/redis-plain.conf +++ /dev/null @@ -1,2 +0,0 @@ -[program:redis] -command = /bin/redis-server --protected-mode no \ No newline at end of file diff --git a/nix/image/configs/supervisor/redis-tls.conf b/nix/image/configs/supervisor/redis-tls.conf deleted file mode 100644 index d9f86bd..0000000 --- a/nix/image/configs/supervisor/redis-tls.conf +++ /dev/null @@ -1,2 +0,0 @@ -[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 \ No newline at end of file diff --git a/nix/image/configs/supervisor/supervisord.conf b/nix/image/configs/supervisor/supervisord.conf deleted file mode 100644 index bed7885..0000000 --- a/nix/image/configs/supervisor/supervisord.conf +++ /dev/null @@ -1,19 +0,0 @@ -[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/* diff --git a/nix/image/haze.nix b/nix/image/haze.nix index 5ce1051..926f0fa 100644 --- a/nix/image/haze.nix +++ b/nix/image/haze.nix @@ -7,9 +7,10 @@ blackfire, coreutils, getent, - writers, shadow, + buildEnv, runCommand, + cacert, callPackage, cronie, redis, @@ -32,20 +33,18 @@ writeShellApplication, vim, helix, - python3Packages, - dnsmasq, - frankenphp, - nushell, }: let - inherit (builtins) toString compareVersions; - inherit (lib) readFile getExe concatStringsSep splitString take optionals; - - version = (fromTOML (readFile ../../Cargo.toml)).package.version; + inherit (builtins) toString; + inherit (lib) readFile getExe concatStringsSep splitString take; phpVersion = concatStringsSep "." (take 2 (splitString "." php.version)); phpEnv = callPackage ./php.nix {inherit debug php;}; - bootstrap = writers.writeNuBin "bootstrap" (readFile ./bootstrap); + bootstrap = writeShellApplication { + name = "bootstrap"; + runtimeInputs = [getent]; + text = readFile ./bootstrap.sh; + }; shadowSetupScript = writeShellApplication { name = "shadow-setup"; text = dockerTools.shadowSetup; @@ -71,6 +70,14 @@ php = phpEnv; }; + phpunitWrapped = majorVersion: + writeShellApplication { + name = "phpunit${toString majorVersion}"; + text = '' + ${phpunitUnwrapped (toString majorVersion)}/bin/phpunit "$@" + ''; + }; + phpunit = writeShellApplication { name = "phpunit"; runtimeInputs = [jq]; @@ -138,10 +145,6 @@ oracle-instantclient vim helix - python3Packages.supervisor - dnsmasq - nushell - getent ]; }; @@ -150,20 +153,11 @@ tag = phpVersion; fromImage = baseImage; - copyToRoot = - [ - phpEnv - phpEnv.packages.composer - phpunit - ] - ++ optionals ((compareVersions phpVersion "8.2") == 1) [ - (frankenphp.override { - php = php.withExtensions (import ./php-ext.nix { - inherit lib php; - enableBlackfire = false; - }); - }) - ]; + copyToRoot = [ + phpEnv + phpEnv.packages.composer + phpunit + ]; }; in dockerTools.buildLayeredImage { @@ -191,14 +185,7 @@ in ''; config = { Cmd = [(getExe bootstrap)]; - Env = [ - "EDITOR=hx" - "WEBROOT=/var/www/html" - "HAZE_IMAGE_VERSION=${toString version}" - ]; + Env = ["EDITOR=hx" "WEBROOT=/var/www/html"]; WorkingDir = "/var/www/html"; - Labels = { - "nl.icewind.haze.version" = toString version; - }; }; } diff --git a/nix/image/configs/nginx.conf b/nix/image/nginx.conf similarity index 85% rename from nix/image/configs/nginx.conf rename to nix/image/nginx.conf index 15a57c3..6e707c2 100644 --- a/nix/image/configs/nginx.conf +++ b/nix/image/nginx.conf @@ -79,7 +79,7 @@ http { } } - include /etc/nginx-app.conf; + include /conf/nginx-app.conf; location ~ \.php(?:$|/) { rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; @@ -109,16 +109,5 @@ http { expires 7d; # Cache-Control policy borrowed from `.htaccess` 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; - } } } diff --git a/nix/image/php-ext.nix b/nix/image/php-ext.nix deleted file mode 100644 index 0a7e53e..0000000 --- a/nix/image/php-ext.nix +++ /dev/null @@ -1,45 +0,0 @@ -{ - 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 - ]) diff --git a/nix/image/configs/php-fpm.conf b/nix/image/php-fpm.conf similarity index 77% rename from nix/image/configs/php-fpm.conf rename to nix/image/php-fpm.conf index 89379d8..e6292fb 100644 --- a/nix/image/configs/php-fpm.conf +++ b/nix/image/php-fpm.conf @@ -1,11 +1,11 @@ [global] -error_log = /var/log/php-fpm-error.log +error_log = /proc/self/fd/2 daemonize = no [www] -access.log =/var/log/php-fpm-access.log +access.log = /proc/self/fd/2 user = haze group = haze @@ -21,7 +21,6 @@ pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 -pm.status_path = /fpm-status clear_env = no diff --git a/nix/image/php.nix b/nix/image/php.nix index 8ef3d31..4fa7ff6 100644 --- a/nix/image/php.nix +++ b/nix/image/php.nix @@ -2,23 +2,60 @@ lib, php, debug ? false, -}: -php.buildEnv { - extensions = import ./php-ext.nix {inherit lib php debug;}; - extraConfig = '' - xdebug.mode=debug,trace,profile - xdebug.start_with_request=trigger - xdebug.discover_client_host=false - xdebug.client_host=hazehost - xdebug.log_level=0 - xdebug.output_dir=/tmp/xdebug +}: let + inherit (builtins) compareVersions; + inherit (lib) optionals; + 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 = '' + xdebug.mode=debug,trace,profile + xdebug.start_with_request=trigger + xdebug.discover_client_host=false + xdebug.client_host=hazehost + xdebug.log_level=0 + xdebug.output_dir=/tmp/xdebug - memory_limit=512M + memory_limit=512M - post_max_size 10G - upload_max_filesize 10G + post_max_size 10G + upload_max_filesize 10G - apc.enable_cli=1 - opcache.enable_cli=1 - ''; -} + apc.enable_cli=1 + opcache.enable_cli=1 + ''; + } diff --git a/nix/image/scripts/install b/nix/image/scripts/install index 35d3f00..2a86fcc 100755 --- a/nix/image/scripts/install +++ b/nix/image/scripts/install @@ -1,22 +1,20 @@ -#!/bin/nu +#!/bin/sh -def main [username: string, password: string] { - 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 +USER=$1 +PASSWORD=$2 - occ maintenance:install --admin-user $username --admin-pass $password --database $sql --database-name $dbName --database-host $dbHost --database-user $dbUser --database-pass $dbPass -} +if [ -z "$USER" ] || [ -z "$PASSWORD" ]; then + 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; diff --git a/nix/image/scripts/integration b/nix/image/scripts/integration index d8187d9..4f73aef 100755 --- a/nix/image/scripts/integration +++ b/nix/image/scripts/integration @@ -1,22 +1,4 @@ -#!/bin/nu +#!/bin/sh -def --wrapped main [feature: path, ...rest] { - 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 -} +cd $WEBROOT/build/integration +./run.sh "$@" diff --git a/nix/image/scripts/nc-auto-config b/nix/image/scripts/nc-auto-config index b7a2c07..fc8d95c 100755 --- a/nix/image/scripts/nc-auto-config +++ b/nix/image/scripts/nc-auto-config @@ -1,4 +1,4 @@ -#!/bin/nu +#!/usr/bin/env bash touch /var/log/nginx/access.log touch /var/log/nginx/error.log @@ -7,30 +7,64 @@ touch /var/log/cron/owncloud.log cp /etc/nc/config.php /var/www/html/config/config.php chmod 0755 /var/www/html/config/config.php -let configName = match $env.SQL { - "oracle" => "oci" - _ => $env.SQL +if [ "$SQL" = "mysql" ] +then + cp /etc/nc/autoconfig_mysql.php /var/www/html/config/autoconfig.php +fi -} -let configPath = $"/etc/nc/autoconfig_($configName).php" +if [ "$SQL" = "mariadb" ] +then + cp /etc/nc/autoconfig_mariadb.php /var/www/html/config/autoconfig.php +fi -if ($configPath | path exists) { - cp $configPath /var/www/html/config/autoconfig.php -} +if [ "$SQL" = "pgsql" ] +then + cp /etc/nc/autoconfig_pgsql.php /var/www/html/config/autoconfig.php +fi -def loadExtraConfig [name: string] { - sed -i $'/\/\/PLACEHOLDER/ r /etc/nc/($name).php' /var/www/html/config/config.php -} +if [ "$SQL" = "oci" ] +then + cp /etc/nc/autoconfig_oci.php /var/www/html/config/autoconfig.php +fi -let extraConfigs = ["S3", "S3S", "S3MB", "S3M", "SWIFT", "SWIFTV3", "AZURE"]; -$extraConfigs | each { - if ($in in $env) { - loadExtraConfig ($in | str downcase) - } -} +if [ -n "${S3:-}" ] +then + sed -i '/\/\/PLACEHOLDER/ r /etc/nc/s3.php' /var/www/html/config/config.php +fi -if ("REDIS_TLS" in $env) { - loadExtraConfig "redis-tls" -} else { - loadExtraConfig "redis-default" -} +if [ -n "${S3S:-}" ] +then + sed -i '/\/\/PLACEHOLDER/ r /etc/nc/s3s.php' /var/www/html/config/config.php +fi + +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 diff --git a/nix/image/scripts/occ b/nix/image/scripts/occ index 07a443b..cf7d6fa 100755 --- a/nix/image/scripts/occ +++ b/nix/image/scripts/occ @@ -1,5 +1,5 @@ -#!/bin/nu +#!/bin/sh -def --wrapped main [...rest] { - XDEBUG_SESSION=haze php $"($env.WEBROOT)/occ" ...$rest -} +export XDEBUG_SESSION=haze + +php $WEBROOT/occ "$@" diff --git a/nix/image/scripts/tests b/nix/image/scripts/tests index 868f225..70691c0 100755 --- a/nix/image/scripts/tests +++ b/nix/image/scripts/tests @@ -1,7 +1,7 @@ -#!/bin/nu +#!/bin/sh -def --wrapped main [...rest] { - cd $env.WEBROOT +cd $WEBROOT - XDEBUG_SESSION=haze phpunit --configuration $"($env.WEBROOT)/tests/phpunit-autotest.xml" ...$rest -} +export XDEBUG_SESSION=haze + +phpunit --configuration $WEBROOT/tests/phpunit-autotest.xml $@ diff --git a/nix/package.nix b/nix/package.nix index c6166f0..fcd6489 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -1,5 +1,6 @@ { rustPlatform, + pkg-config, lib, git, }: let @@ -9,7 +10,7 @@ src = sourceByRegex ../. ["Cargo.*" "(src|certificates)(/.*)?"]; version = (fromTOML (readFile ../Cargo.toml)).package.version; in - rustPlatform.buildRustPackage { + rustPlatform.buildRustPackage rec { pname = "haze"; inherit src version; @@ -19,7 +20,7 @@ in cargoLock = { lockFile = ../Cargo.lock; outputHashes = { - "hyper-reverse-proxy-0.5.2-dev" = "sha256-awmj5aLFTea+kj81cwmfP1HWlWezwEKfyQSUJWjtamk="; + "hyper-reverse-proxy-0.5.2-dev" = "sha256-+ebi4FVVkiOpf75e8K5oGkHJBYQjLNJhUPNj+78zd7Q="; }; }; } diff --git a/src/args.rs b/src/args.rs index 59bca87..9b7a2cc 100644 --- a/src/args.rs +++ b/src/args.rs @@ -165,7 +165,6 @@ impl LogService { #[derive(Debug, Clone, Eq, PartialEq)] pub enum ExecService { Db, - Service(Service), } impl HazeArgs { @@ -233,14 +232,6 @@ impl HazeArgs { args.next(); 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, }; diff --git a/src/database.rs b/src/database.rs index 0bc31d7..ff969a3 100644 --- a/src/database.rs +++ b/src/database.rs @@ -219,6 +219,14 @@ impl Database { } }), }), + cmd: if self.image() == "mysql:8" { + Some(vec![ + "--default-authentication-plugin".into(), + "mysql_native_password".into(), + ]) + } else { + None + }, ..Default::default() }; let id = docker diff --git a/src/git.rs b/src/git.rs index fc31255..3a797c3 100644 --- a/src/git.rs +++ b/src/git.rs @@ -2,15 +2,11 @@ use crate::config::HazeConfig; use crate::Result; use git2::build::CheckoutBuilder; use git2::{Branch, BranchType, Repository, RepositoryState}; -use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use miette::{Context, IntoDiagnostic}; -use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; -use rayon::ThreadPoolBuilder; use std::fs::read_dir; use std::iter::once; use std::path::PathBuf; use std::process::Command; -use std::time::Duration; fn find_app_repos(config: &HazeConfig) -> Result> { let apps_dirs = once(config.sources_root.as_path().join("apps")) @@ -87,66 +83,38 @@ const GIT_BINARY: &str = match option_env!("GIT_BINARY") { pub fn pull_all(config: &HazeConfig) -> Result<()> { let (max_app, max_branch) = longest_app_branch(config)?; - let progress = MultiProgress::new(); - let pull_style = ProgressStyle::with_template("{spinner:.green} {msg}").unwrap(); + for app_dir in find_app_repos(config)? { + let app_name = app_dir.file_name().unwrap().to_string_lossy(); + let repo = Repository::init(&app_dir) + .into_diagnostic() + .wrap_err_with(|| format!("Failed to open repository {}", app_dir.display()))?; + let branch_name = current_branch_name(&repo).unwrap_or("unknown".into()); - let pool = ThreadPoolBuilder::new() - .num_threads(8) - .build() - .into_diagnostic()?; - let repos = find_app_repos(config)?.collect::>(); + print!( + "{app_name: output, - Err(error) => { - bar.set_message(msg(&format!(" ⨯ {error}"))); - return; - } - }; - - if output.status.success() { - bar.set_message(msg(" ✓")); - } else { - let err = String::from_utf8_lossy(&output.stderr); - let err_line = err.lines().next().unwrap(); - bar.set_message(msg(&format!(" ⨯ {err_line}"))); - } - bar.finish(); - }); - }); + let output = Command::new(GIT_BINARY) + .arg("pull") + .current_dir(&app_dir) + .output() + .into_diagnostic() + .wrap_err_with(|| format!("Failed to run git pull for {}", app_dir.display()))?; + if output.status.success() { + println!(" ✓"); + } else { + println!(" ❌"); + eprintln!("{}", String::from_utf8_lossy(&output.stderr)) + } + } Ok(()) } diff --git a/src/image.rs b/src/image.rs index e24abfd..94da352 100644 --- a/src/image.rs +++ b/src/image.rs @@ -5,48 +5,11 @@ use futures_util::StreamExt; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; use miette::{IntoDiagnostic, Result, WrapErr}; 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 { - 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 { docker.inspect_image(image).await.is_ok() } -pub async fn image_version(docker: &Docker, image: &str) -> Option { - 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<()> { if image_exists(docker, image).await { force_pull_image(docker, image).await?; diff --git a/src/main.rs b/src/main.rs index d999b7c..2e4de9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,9 +148,6 @@ async fn main() -> Result { root, } => { let cloud = Cloud::get_by_filter(&docker, filter, &config).await?; - let env = get_forward_env(); - let tty = atty::is(atty::Stream::Stdout); - match service { None => { let command = if command.is_empty() { @@ -158,7 +155,8 @@ async fn main() -> Result { } else { command }; - + let env = get_forward_env(); + let tty = atty::is(atty::Stream::Stdout); let user = if root { "root" } else { "haze" }; if tty { exec_tty(&docker, &cloud.id, user, command, env).await?; @@ -167,42 +165,19 @@ async fn main() -> Result { } } Some(ExecService::Db) => { - let command = if command.is_empty() { - vec!["bash".to_string()] - } else { - command - }; - - cloud.db().exec_sh(&docker, &cloud.id, command, tty).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?; - } + cloud + .db() + .exec_sh( + &docker, + &cloud.id, + if command.is_empty() { + vec!["bash".to_string()] + } else { + command + }, + atty::is(atty::Stream::Stdout), + ) + .await?; } } } @@ -658,7 +633,12 @@ async fn setup(docker: &Docker, options: CloudOptions, config: &HazeConfig) -> R for service in cloud.services() { for cmd in service.post_setup(docker, &cloud.id, config).await? { cloud - .exec(docker, cmd, false, Vec::::default()) + .exec( + docker, + shell_words::split(&cmd).into_diagnostic()?, + false, + Vec::::default(), + ) .await?; } } diff --git a/src/php.rs b/src/php.rs index d1abaa2..1451108 100644 --- a/src/php.rs +++ b/src/php.rs @@ -1,7 +1,6 @@ -use owo_colors::OwoColorize; use crate::config::ProxyConfig; use crate::database::Database; -use crate::image::{image_version, pull_image, ImageVersion}; +use crate::image::pull_image; use crate::network::ensure_network_exists; use crate::service::Service; use crate::service::ServiceTrait; @@ -124,17 +123,6 @@ impl PhpVersion { ) -> Result { ensure_network_exists(docker, "haze").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 { name: Some(id.to_string()), ..CreateContainerOptions::default() @@ -160,11 +148,6 @@ impl PhpVersion { 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! { "haze-type".to_string() => "cloud".to_string(), "haze-db".to_string() => db.name().to_string(), diff --git a/src/proxy.rs b/src/proxy.rs index 4784a18..d5a3b0e 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -5,34 +5,26 @@ use axum::http::header::HOST; use axum::http::HeaderValue; use axum::{ body::Body, - extract::Request, + extract::{Request, State}, response::{IntoResponse, Response}, + Router, }; 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_util::rt::TokioIo; use hyper_util::{client::legacy::connect::HttpConnector, rt::TokioExecutor}; use miette::{miette, IntoDiagnostic}; use std::collections::HashMap; -use std::convert::Infallible; use std::fs::{create_dir_all, set_permissions}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; -use std::pin::pin; use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::time::Duration; -use tokio::io::{AsyncRead, AsyncWrite}; use tokio::net::UnixListener; use tokio::signal::ctrl_c; use tokio::spawn; use tokio::time::sleep; -use tokio_stream::wrappers::{TcpListenerStream, UnixListenerStream}; use tracing::{debug, error, info}; struct ActiveInstances { @@ -171,26 +163,20 @@ async fn serve(instances: ActiveInstances, listen: String, base_address: String) ctrl_c().await.ok(); }; - let state = AppState { + let app = Router::new().fallback(handler).with_state(AppState { instances: instances.clone(), base_address: base_address.clone(), proxy_client: Arc::new(proxy_client), - }; + }); if !listen.starts_with('/') { let addr: SocketAddr = listen.parse().into_diagnostic()?; let listener = tokio::net::TcpListener::bind(addr).await.unwrap(); println!("listening on {}", listener.local_addr().unwrap()); - let mut connections = pin!(TcpListenerStream::new(listener).take_until(cancel)); - - while let Some(stream) = connections.next().await { - match stream { - Ok(stream) => handle_connection(state.clone(), stream), - Err(error) => { - error!(%error, "connection failed"); - } - } - } + axum::serve(listener, app) + .with_graceful_shutdown(cancel) + .await + .unwrap(); } else { let listen: PathBuf = listen.into(); if let Some(parent) = listen.parent() { @@ -201,42 +187,18 @@ async fn serve(instances: ActiveInstances, listen: String, base_address: String) } let _ = tokio::fs::remove_file(&listen).await; - let listener = UnixListener::bind(&listen).unwrap(); - println!("listening on {}", listen.display()); + let uds = UnixListener::bind(&listen).unwrap(); set_permissions(&listen, PermissionsExt::from_mode(0o666)).into_diagnostic()?; - let mut connections = pin!(UnixListenerStream::new(listener).take_until(cancel)); - - while let Some(stream) = connections.next().await { - match stream { - Ok(stream) => handle_connection(state.clone(), stream), - Err(error) => { - error!(%error, "connection failed"); - } - } - } + axum::serve(uds, app) + .with_graceful_shutdown(cancel) + .await + .unwrap(); } Ok(()) } -fn handle_connection( - 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( host: Option<&HeaderValue>, instances: &ActiveInstances, @@ -270,9 +232,9 @@ async fn get_remote( } } -type Client = hyper_util::client::legacy::Client; +type Client = hyper_util::client::legacy::Client; -async fn handler(state: AppState, mut req: Request) -> Result { +async fn handler(State(state): State, mut req: Request) -> Result { let host = req.headers().get(HOST).cloned(); let remote = match get_remote(host.as_ref(), &state.instances, &state.base_address).await { Ok(remote) => remote, @@ -297,13 +259,13 @@ async fn handler(state: AppState, mut req: Request) -> Result Ok(response.map(Body::new)), Err(error) => { - error!(?error, "error while proxying request"); + error!(%error, "error while proxying request"); Ok(StatusCode::BAD_REQUEST.into_response()) } } diff --git a/src/service.rs b/src/service.rs index c514449..67325c3 100644 --- a/src/service.rs +++ b/src/service.rs @@ -14,7 +14,6 @@ mod sftp; mod redis; mod sharded; mod smb; -mod webhook; use crate::cloud::CloudOptions; use crate::config::{HazeConfig, Preset, ProxyConfig}; @@ -30,10 +29,9 @@ pub use crate::service::office::Office; pub use crate::service::onlyoffice::OnlyOffice; pub use crate::service::push::NotifyPush; use crate::service::redis::Redis; -use crate::service::sftp::{Sftp, SftpKey}; +use crate::service::sftp::Sftp; use crate::service::sharded::{Sharding, ShardingMigrate, ShardingMigrateUnset, SingleShard}; use crate::service::smb::Smb; -use crate::service::webhook::Webhook; use bollard::models::ContainerState; use bollard::Docker; use enum_dispatch::enum_dispatch; @@ -116,7 +114,7 @@ pub trait ServiceTrait { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(Vec::new()) } @@ -194,14 +192,6 @@ pub trait ServiceTrait { fn proxy_port(&self) -> u16 { 80 } - - fn exec_user(&self) -> &'static str { - "root" - } - - fn exec_shell(&self) -> &'static str { - "bash" - } } #[derive(Clone, Eq, PartialEq, Debug)] @@ -217,19 +207,6 @@ 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( Copy, Clone, Debug, PartialEq, EnumString, EnumMessage, EnumIter, IntoStaticStr, Display, )] @@ -250,7 +227,6 @@ pub enum ServiceType { /// Ldap admin interface LdapAdmin, /// OnlyOffice - #[strum(serialize = "onlyoffice", serialize = "only-office")] OnlyOffice, /// Libre office online Office, @@ -276,8 +252,6 @@ pub enum ServiceType { Dav, /// Sftp external storage Sftp, - /// Sftp external storage with public key authentication - SftpKey, /// ownCloud instance for migration Oc, /// Imaginary for preview generation @@ -307,10 +281,6 @@ pub enum ServiceType { Redis, /// External redis instance with TLS RedisTls, - /// Use FrankenPHP instead of PHP-FPM - FrankenPhp, - /// Webhook test listener - Webhook, } #[enum_dispatch] @@ -329,7 +299,6 @@ pub enum Service { ShardingMigrate(ShardingMigrate), ShardingMigrateUnset(ShardingMigrateUnset), Sftp(Sftp), - SftpKey(SftpKey), Kaspersky(Kaspersky), KasperskyIcap(KasperskyIcap), Clam(Clam), @@ -341,8 +310,6 @@ pub enum Service { Mail(Mail), Redis(Redis), RedisTls(RedisTls), - FrankenPhp(FrankenPhp), - Webhook(Webhook), Preset(PresetService), } @@ -373,7 +340,6 @@ impl Service { } ServiceType::Dav => Some(vec![Service::Dav(Dav)]), ServiceType::Sftp => Some(vec![Service::Sftp(Sftp)]), - ServiceType::SftpKey => Some(vec![Service::SftpKey(SftpKey)]), ServiceType::Oc => Some(vec![Service::Oc(Oc)]), ServiceType::Imaginary => Some(vec![Service::Imaginary(Imaginary)]), ServiceType::Kaspersky => Some(vec![Service::Kaspersky(Kaspersky)]), @@ -386,8 +352,6 @@ impl Service { ServiceType::Mail => Some(vec![Service::Mail(Mail)]), ServiceType::Redis => Some(vec![Service::Redis(Redis)]), ServiceType::RedisTls => Some(vec![Service::RedisTls(RedisTls)]), - ServiceType::FrankenPhp => Some(vec![Service::FrankenPhp(FrankenPhp)]), - ServiceType::Webhook => Some(vec![Service::Webhook(Webhook)]), } } else { presets @@ -450,29 +414,15 @@ impl ServiceTrait for PresetService { _docker: &Docker, _cloud_id: &str, config: &HazeConfig, - ) -> Result>> { + ) -> Result> { let preset = get_preset(&config.preset, &self.0).ok_or_else(|| Report::msg("invalid preset"))?; let mut commands: Vec<_> = preset .apps .iter() - .map(|app| { - vec![ - "occ".into(), - "app:enable".into(), - app.clone(), - "--force".into(), - ] - }) + .map(|app| format!("occ app:enable {app} --force")) .collect(); - for cmnd in &preset.commands { - commands.push(shell_words::split(cmnd).into_diagnostic()?); - } - + commands.extend_from_slice(&preset.commands); Ok(commands) } } - -fn split_cmnd(s: &str) -> Vec { - s.split(' ').map(String::from).collect() -} diff --git a/src/service/clam.rs b/src/service/clam.rs index 7221309..74b790d 100644 --- a/src/service/clam.rs +++ b/src/service/clam.rs @@ -2,7 +2,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::exec::exec; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig}; use bollard::query_parameters::CreateContainerOptions; @@ -85,13 +85,14 @@ impl ServiceTrait for ClamIcap { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ config:app:set files_antivirus av_mode --value=icap"), - split_cmnd("occ config:app:set files_antivirus av_host --value=clamav-icap"), - split_cmnd("occ config:app:set files_antivirus av_port --value=1344"), - split_cmnd("occ config:app:set files_antivirus av_icap_request_service --value=avscan"), - split_cmnd("occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found"), + "occ config:app:set files_antivirus av_mode --value=icap".into(), + "occ config:app:set files_antivirus av_host --value=clamav-icap".into(), + "occ config:app:set files_antivirus av_port --value=1344".into(), + "occ config:app:set files_antivirus av_icap_request_service --value=avscan".into(), + "occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found" + .into(), ]) } } @@ -170,7 +171,7 @@ impl ServiceTrait for ClamIcapTls { docker: &Docker, cloud_id: &str, config: &HazeConfig, - ) -> Result>> { + ) -> Result> { let mut cert = Vec::new(); exec( docker, @@ -190,13 +191,14 @@ impl ServiceTrait for ClamIcapTls { .wrap_err("Failed to write icap certificate")?; Ok(vec![ - split_cmnd("occ config:app:set files_antivirus av_mode --value=icap"), - split_cmnd("occ config:app:set files_antivirus av_icap_tls --value=1"), - split_cmnd("occ config:app:set files_antivirus av_host --value=clamav-icap-tls"), - split_cmnd("occ config:app:set files_antivirus av_port --value=1345"), - split_cmnd("occ config:app:set files_antivirus av_icap_request_service --value=avscan"), - split_cmnd("occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found"), - split_cmnd("occ security:certificates:import data/icap-cert.pem"), + "occ config:app:set files_antivirus av_mode --value=icap".into(), + "occ config:app:set files_antivirus av_icap_tls --value=1".into(), + "occ config:app:set files_antivirus av_host --value=clamav-icap-tls".into(), + "occ config:app:set files_antivirus av_port --value=1345".into(), + "occ config:app:set files_antivirus av_icap_request_service --value=avscan".into(), + "occ config:app:set files_antivirus av_icap_response_header --value=X-Infection-Found" + .into(), + "occ security:certificates:import data/icap-cert.pem".into(), ]) } } @@ -219,10 +221,10 @@ impl ServiceTrait for Clam { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ config:app:set files_antivirus av_mode --value=executable"), - split_cmnd("occ config:app:set files_antivirus av_path --value=/bin/clamscan"), + "occ config:app:set files_antivirus av_mode --value=executable".into(), + "occ config:app:set files_antivirus av_path --value=/bin/clamscan".into(), ]) } } @@ -292,12 +294,10 @@ impl ServiceTrait for ClamSocket { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ config:app:set files_antivirus av_mode --value=socket"), - split_cmnd( - "occ config:app:set files_antivirus av_socket --value=tcp://clamav-socket:3310", - ), + "occ config:app:set files_antivirus av_mode --value=socket".into(), + "occ config:app:set files_antivirus av_socket --value=tcp://clamav-socket:3310".into(), ]) } } diff --git a/src/service/dav.rs b/src/service/dav.rs index e0b20f3..d328925 100644 --- a/src/service/dav.rs +++ b/src/service/dav.rs @@ -1,7 +1,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::config::ContainerCreateBody; use bollard::models::{EndpointSettings, HostConfig, NetworkingConfig}; @@ -76,12 +76,12 @@ impl ServiceTrait for Dav { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ files_external:create dav dav password::password"), - split_cmnd("occ files_external:config 1 host dav"), - split_cmnd("occ files_external:config 1 user test"), - split_cmnd("occ files_external:config 1 password test"), + "occ files_external:create dav dav password::password".into(), + "occ files_external:config 1 host dav".into(), + "occ files_external:config 1 user test".into(), + "occ files_external:config 1 password test".into(), ]) } } diff --git a/src/service/imaginary.rs b/src/service/imaginary.rs index 4ec4d96..693c173 100644 --- a/src/service/imaginary.rs +++ b/src/service/imaginary.rs @@ -1,7 +1,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::config::NetworkingConfig; use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig}; @@ -71,14 +71,11 @@ impl ServiceTrait for Imaginary { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd( - "occ config:system:set enabledPreviewProviders 0 --value='OC\\Preview\\Imaginary'", - ), - split_cmnd( - "occ config:system:set preview_imaginary_url --value='http://imaginary:9000'", - ), + "occ config:system:set enabledPreviewProviders 0 --value='OC\\Preview\\Imaginary'" + .into(), + "occ config:system:set preview_imaginary_url --value='http://imaginary:9000'".into(), ]) } } diff --git a/src/service/kaspersky.rs b/src/service/kaspersky.rs index 1c0a67f..bc4f08a 100644 --- a/src/service/kaspersky.rs +++ b/src/service/kaspersky.rs @@ -2,7 +2,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::exec::exec; use crate::image::{image_exists, pull_image}; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig}; use bollard::query_parameters::CreateContainerOptions; @@ -101,11 +101,11 @@ impl ServiceTrait for Kaspersky { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ config:app:set files_antivirus av_mode --value=kaspersky"), - split_cmnd("occ config:app:set files_antivirus av_host --value=kaspersky"), - split_cmnd("occ config:app:set files_antivirus av_port --value=80"), + "occ config:app:set files_antivirus av_mode --value=kaspersky".into(), + "occ config:app:set files_antivirus av_host --value=kaspersky".into(), + "occ config:app:set files_antivirus av_port --value=80".into(), ]) } } @@ -187,15 +187,13 @@ impl ServiceTrait for KasperskyIcap { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ config:app:set files_antivirus av_mode --value=icap"), - split_cmnd("occ config:app:set files_antivirus av_host --value=kaspersky-icap"), - split_cmnd("occ config:app:set files_antivirus av_port --value=1344"), - split_cmnd("occ config:app:set files_antivirus av_icap_request_service --value=req"), - split_cmnd( - "occ config:app:set files_antivirus av_icap_response_header --value=X-Virus-ID", - ), + "occ config:app:set files_antivirus av_mode --value=icap".into(), + "occ config:app:set files_antivirus av_host --value=kaspersky-icap".into(), + "occ config:app:set files_antivirus av_port --value=1344".into(), + "occ config:app:set files_antivirus av_icap_request_service --value=req".into(), + "occ config:app:set files_antivirus av_icap_response_header --value=X-Virus-ID".into(), ]) } } diff --git a/src/service/ldap.rs b/src/service/ldap.rs index 4f317e6..aa082b0 100644 --- a/src/service/ldap.rs +++ b/src/service/ldap.rs @@ -1,7 +1,7 @@ use crate::cloud::CloudOptions; use crate::config::{HazeConfig, ProxyConfig}; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::config::NetworkingConfig; use bollard::models::{ContainerCreateBody, ContainerState, EndpointSettings, HostConfig}; @@ -86,46 +86,6 @@ impl ServiceTrait for Ldap { ) -> Result { self.is_running(docker, cloud_id).await } - - async fn post_setup( - &self, - _docker: &Docker, - _cloud_id: &str, - _config: &HazeConfig, - ) -> Result>> { - 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> { - 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)] @@ -225,6 +185,8 @@ impl ServiceTrait for LdapAdmin { return Err(Report::msg("ldap admin not started")); }; let addr = proxy.addr(&id, IpAddr::from_str(&ip).unwrap()); - Ok(Some(format!("Ldap admin running at: {addr}"))) + Ok(Some(format!( + "Ldap admin running at: {addr} with 'cn=admin,dc=example,dc=org' and password 'haze'" + ))) } } diff --git a/src/service/mail.rs b/src/service/mail.rs index ad40471..c52fdac 100644 --- a/src/service/mail.rs +++ b/src/service/mail.rs @@ -1,7 +1,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig}; use bollard::query_parameters::CreateContainerOptions; @@ -70,14 +70,14 @@ impl ServiceTrait for Mail { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ config:system:set mail_smtpmode --value smtp"), - split_cmnd("occ config:system:set mail_sendmailmode --value smtp"), - split_cmnd("occ config:system:set mail_domain --value haze"), - split_cmnd("occ config:system:set mail_smtphost --value mail"), - split_cmnd("occ config:system:set mail_smtpport --value 25"), - split_cmnd("occ user:setting admin settings email admin@haze"), + "occ config:system:set mail_smtpmode --value smtp".into(), + "occ config:system:set mail_sendmailmode --value smtp".into(), + "occ config:system:set mail_domain --value haze".into(), + "occ config:system:set mail_smtphost --value mail".into(), + "occ config:system:set mail_smtpport --value 25".into(), + "occ user:setting admin settings email admin@haze".into(), ]) } } diff --git a/src/service/objectstore.rs b/src/service/objectstore.rs index 20e586c..c0767e0 100644 --- a/src/service/objectstore.rs +++ b/src/service/objectstore.rs @@ -2,7 +2,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::exec::exec; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::models::{ ContainerCreateBody, ContainerState, EndpointSettings, HostConfig, NetworkingConfig, @@ -247,18 +247,18 @@ impl ServiceTrait for ObjectStore { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { match self { ObjectStore::S3 => Ok(vec![ - split_cmnd("occ files_external:create s3 amazons3 amazons3::accesskey"), - split_cmnd("occ files_external:config 1 bucket ext"), - split_cmnd("occ files_external:config 1 hostname s3"), - split_cmnd("occ files_external:config 1 port 9000"), - split_cmnd("occ files_external:config 1 use_ssl false"), - split_cmnd("occ files_external:config 1 use_path_style true"), - split_cmnd("occ files_external:config 1 key minio"), - split_cmnd("occ files_external:config 1 secret minio123"), - split_cmnd("mc alias set s3 http://s3:9000 minio minio123"), + "occ files_external:create s3 amazons3 amazons3::accesskey".into(), + "occ files_external:config 1 bucket ext".into(), + "occ files_external:config 1 hostname s3".into(), + "occ files_external:config 1 port 9000".into(), + "occ files_external:config 1 use_ssl false".into(), + "occ files_external:config 1 use_path_style true".into(), + "occ files_external:config 1 key minio".into(), + "occ files_external:config 1 secret minio123".into(), + "mc alias set s3 http://s3:9000 minio minio123".into(), ]), // ObjectStore::S3s => Ok(vec![ // "occ files_external:create s3 amazons3 amazons3::accesskey".into(), diff --git a/src/service/oc.rs b/src/service/oc.rs index 296b2a5..2eb3a22 100644 --- a/src/service/oc.rs +++ b/src/service/oc.rs @@ -83,7 +83,7 @@ impl ServiceTrait for Oc { docker: &Docker, cloud_id: &str, config: &HazeConfig, - ) -> Result>> { + ) -> Result> { if let Some(ip) = self.get_ips(docker, cloud_id).await?.next() { let container = self.container_name(cloud_id).unwrap(); let addr = config.proxy.addr(&container, ip); diff --git a/src/service/office.rs b/src/service/office.rs index e7db10d..4cd72c9 100644 --- a/src/service/office.rs +++ b/src/service/office.rs @@ -32,23 +32,6 @@ impl ServiceTrait for Office { config: &HazeConfig, _options: &CloudOptions, ) -> Result> { - 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"; pull_image(docker, image).await?; let container_id = self.container_name(cloud_id).unwrap(); @@ -56,31 +39,28 @@ impl ServiceTrait for Office { name: Some(container_id.clone()), ..CreateContainerOptions::default() }); - let mut env = - vec![r#"extra_params=--o:ssl.enable=false --o:ssl.termination=true --o:net.frame_ancestors=*"#.to_string()]; + let mut env = vec!["extra_params=--o:ssl.enable=false --o:ssl.termination=true"]; - let proxy_base = &config.proxy.address; let clean_id = container_id.strip_prefix("haze-").unwrap_or(&container_id); - if !proxy_base.is_empty() { - env.push(format!("server_name={clean_id}.{}", config.proxy.address)); - } - - let clean_cloud_id = cloud_id.strip_prefix("haze-").unwrap_or(cloud_id); - let hosts = if proxy_base.is_empty() { - vec![] - } else { - vec![ - format!("{proxy_base}:{gateway}"), - format!("{clean_cloud_id}.{proxy_base}:{gateway}"), - ] + let server_name_opt = match (&config.proxy.address, config.proxy.https) { + (public, true) if !public.is_empty() => { + 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() { + env.push(&server_name_opt); + } + let config = ContainerCreateBody { image: Some(image.into()), - env: Some(env), + env: Some(env.into_iter().map(String::from).collect()), host_config: Some(HostConfig { network_mode: Some(network.to_string()), - extra_hosts: Some(hosts), ..Default::default() }), labels: Some(hashmap! { @@ -119,7 +99,7 @@ impl ServiceTrait for Office { docker: &Docker, cloud_id: &str, config: &HazeConfig, - ) -> Result>> { + ) -> Result> { let container = &self.container_name(cloud_id).unwrap(); let info = docker .inspect_container(container, None) @@ -147,27 +127,19 @@ impl ServiceTrait for Office { } else { return Err(Report::msg("office not started")); }; - let public = config - .proxy - .addr_with_port(container, ip, self.proxy_port()); - Ok(vec![ - vec![ - "occ".into(), - "config:app:set".into(), - "richdocuments".into(), - "public_wopi_url".into(), - "--value".into(), - public, - ], - vec![ - "occ".into(), - "richdocuments:setup".into(), - "--wopi-url".into(), - "http://office:9980".into(), - "--callback-url".into(), - "http://cloud".into(), - ], + format!( + r#"occ config:app:set richdocuments wopi_url --value="http://{}:9980""#, + ip + ), + format!( + r#"occ config:app:set richdocuments public_wopi_url --value="{}""#, + config.proxy.addr_with_port(container, ip, 9980) + ), + format!( + r#"occ config:app:set richdocuments wopi_root --value="http://{}""#, + cloud_id + ), ]) } diff --git a/src/service/onlyoffice.rs b/src/service/onlyoffice.rs index fa12c2c..b7c8a14 100644 --- a/src/service/onlyoffice.rs +++ b/src/service/onlyoffice.rs @@ -2,7 +2,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::exec::exec; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::models::{ ContainerCreateBody, ContainerState, EndpointSettings, HostConfig, NetworkingConfig, @@ -82,7 +82,7 @@ impl ServiceTrait for OnlyOffice { docker: &Docker, cloud_id: &str, config: &HazeConfig, - ) -> Result>> { + ) -> Result> { let info = docker .inspect_container(&self.container_name(cloud_id).unwrap(), None) .await @@ -137,44 +137,16 @@ impl ServiceTrait for OnlyOffice { ); Ok(vec![ - vec![ - "occ".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"), + format!("occ config:app:set onlyoffice DocumentServerUrl --value {addr}/"), + format!("occ config:app:set onlyoffice jwt_secret --value {secret}"), + "occ onlyoffice:documentserver --check".into(), ]) } else { Ok(vec![ - vec![ - "occ".into(), - "config:app:set".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"), + format!("occ config:app:set onlyoffice DocumentServerUrl --value https://{ip}/"), + "occ config:app:set onlyoffice verify_peer_off --value true".into(), + format!("occ config:app:set onlyoffice jwt_secret --value {secret}"), + "occ onlyoffice:documentserver --check".into(), ]) } } diff --git a/src/service/push.rs b/src/service/push.rs index b0bbab2..22b3ac2 100644 --- a/src/service/push.rs +++ b/src/service/push.rs @@ -87,7 +87,7 @@ impl ServiceTrait for NotifyPush { docker: &Docker, cloud_id: &str, config: &HazeConfig, - ) -> Result>> { + ) -> Result> { let mut ips: Vec<_> = self.get_ips(docker, cloud_id).await?.collect(); if let Ok(local_interfaces) = list_afinet_netifas() { ips.extend(local_interfaces.into_iter().map(|(_, ip)| ip)); @@ -97,14 +97,10 @@ impl ServiceTrait for NotifyPush { .iter() .enumerate() .map(|(i, ip)| { - vec![ - "occ".into(), - "config:system:set".into(), - "trusted_proxies".into(), - (i + 1).to_string(), - "--value".into(), - ip.to_string(), - ] + format!( + "occ config:system:set trusted_proxies {} --value {ip}", + i + 1 + ) }) .collect(); @@ -112,7 +108,7 @@ impl ServiceTrait for NotifyPush { config .proxy .addr_with_port(&self.container_name(cloud_id).unwrap(), ips[0], 7867); - commands.push(vec!["occ".into(), "notify_push:setup".into(), addr]); + commands.push(format!("occ notify_push:setup {}", addr)); Ok(commands) } diff --git a/src/service/redis.rs b/src/service/redis.rs index 6d5d5e6..29a22ee 100644 --- a/src/service/redis.rs +++ b/src/service/redis.rs @@ -1,7 +1,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig}; use bollard::query_parameters::CreateContainerOptions; @@ -70,13 +70,7 @@ impl ServiceTrait for Redis { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { - Ok(vec![split_cmnd( - "occ config:system:set redis host --value redis", - )]) - } - - fn exec_shell(&self) -> &'static str { - "sh" + ) -> Result> { + Ok(vec!["occ config:system:set redis host --value redis".into()]) } } diff --git a/src/service/sftp.rs b/src/service/sftp.rs index 1f47a40..80405e2 100644 --- a/src/service/sftp.rs +++ b/src/service/sftp.rs @@ -1,14 +1,13 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +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::{Context, IntoDiagnostic}; -use std::fs::{create_dir_all, write}; +use miette::IntoDiagnostic; #[derive(Debug, Clone, Eq, PartialEq)] pub struct Sftp; @@ -51,10 +50,7 @@ impl ServiceTrait for Sftp { } }), }), - cmd: Some(vec![ - "test:test:::data".into(), - "ldaptest:test:::data".into(), - ]), + cmd: Some(vec!["test:test:::data".into()]), ..Default::default() }; let id = docker @@ -79,119 +75,13 @@ impl ServiceTrait for Sftp { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { - Ok(vec![ - split_cmnd("occ files_external:create sftp sftp password::password"), - split_cmnd("occ files_external:config 1 host sftp"), - split_cmnd("occ files_external:config 1 user test"), - split_cmnd("occ files_external:config 1 root data"), - 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> { - 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 { - 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>> { 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(), - ], + "occ files_external:create sftp sftp password::password".into(), + "occ files_external:config 1 host sftp".into(), + "occ files_external:config 1 user test".into(), + "occ files_external:config 1 root data".into(), + "occ files_external:config 1 password test".into(), ]) } } diff --git a/src/service/smb.rs b/src/service/smb.rs index 08f69bd..a40b105 100644 --- a/src/service/smb.rs +++ b/src/service/smb.rs @@ -1,7 +1,7 @@ use crate::cloud::CloudOptions; use crate::config::HazeConfig; use crate::image::pull_image; -use crate::service::{split_cmnd, ServiceTrait}; +use crate::service::ServiceTrait; use crate::Result; use bollard::models::{ContainerCreateBody, EndpointSettings, HostConfig, NetworkingConfig}; use bollard::query_parameters::CreateContainerOptions; @@ -40,10 +40,8 @@ impl ServiceTrait for Smb { }), env: Some(vec![ "ACCOUNT_test=test".into(), - "ACCOUNT_ldaptest=test".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_ldaptest=[ldaptest]; path=/tmp; valid users = ldaptest; guest ok = no; read only = no; browseable = yes".into(), ]), labels: Some(hashmap! { "haze-type".into() => self.name().into(), @@ -81,17 +79,13 @@ impl ServiceTrait for Smb { _docker: &Docker, _cloud_id: &str, _config: &HazeConfig, - ) -> Result>> { + ) -> Result> { Ok(vec![ - split_cmnd("occ files_external:create smb smb password::password"), - split_cmnd("occ files_external:config 1 host smb"), - split_cmnd("occ files_external:config 1 user test"), - split_cmnd("occ files_external:config 1 password test"), - split_cmnd("occ files_external:config 1 share test"), + "occ files_external:create smb smb password::password".into(), + "occ files_external:config 1 host smb".into(), + "occ files_external:config 1 user test".into(), + "occ files_external:config 1 password test".into(), + "occ files_external:config 1 share test".into(), ]) } - - fn exec_shell(&self) -> &'static str { - "sh" - } } diff --git a/src/service/webhook.rs b/src/service/webhook.rs deleted file mode 100644 index e7ebae0..0000000 --- a/src/service/webhook.rs +++ /dev/null @@ -1,75 +0,0 @@ -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> { - 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 { - Some(format!("{}-webhook", cloud_id)) - } - - fn proxy_port(&self) -> u16 { - 8080 - } - - fn exec_shell(&self) -> &'static str { - "" - } -} diff --git a/src/sources.rs b/src/sources.rs index ccfe564..b99c54a 100644 --- a/src/sources.rs +++ b/src/sources.rs @@ -122,7 +122,7 @@ pub async fn download_nc(config: &HazeConfig, version: &str) -> Result