mirror of
https://github.com/moghtech/komodo.git
synced 2026-03-19 15:10:47 -05:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4aac301852 | ||
|
|
b375708bbd | ||
|
|
10b6a9482b | ||
|
|
84d45c5df8 | ||
|
|
c6559814b1 | ||
|
|
c8c080183f | ||
|
|
597b67f799 | ||
|
|
ec52d5f422 | ||
|
|
34806304d6 | ||
|
|
87953d5495 | ||
|
|
b6c7c80c95 | ||
|
|
77e568d5c3 | ||
|
|
699fc51cf7 | ||
|
|
21029c90b7 | ||
|
|
6b0530eb7f | ||
|
|
f7061c7225 | ||
|
|
750f698369 | ||
|
|
ec5ef42298 | ||
|
|
46820b0044 | ||
|
|
425a6648f7 |
8
.vscode/tasks.json
vendored
8
.vscode/tasks.json
vendored
@@ -100,14 +100,6 @@
|
||||
"cwd": "${workspaceFolder}/lib/monitor_client"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "cargo",
|
||||
"command": "publish",
|
||||
"label": "publish monitor cli",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/cli"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "docker compose up -d",
|
||||
|
||||
327
Cargo.lock
generated
327
Cargo.lock
generated
@@ -37,6 +37,46 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-wincon",
|
||||
"concolor-override",
|
||||
"concolor-query",
|
||||
"is-terminal",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.69"
|
||||
@@ -51,7 +91,7 @@ checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -86,9 +126,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "aws-config"
|
||||
version = "0.54.1"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3d1e2a1f1ab3ac6c4b884e37413eaa03eb9d901e4fc68ee8f5c1d49721680e"
|
||||
checksum = "1854be4730cc87602316707045a5c0585287419d54f293bbb52a82c895d9086a"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-http",
|
||||
@@ -102,6 +142,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"aws-types",
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"hex",
|
||||
"http",
|
||||
"hyper",
|
||||
@@ -115,12 +156,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-credential-types"
|
||||
version = "0.54.1"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb0696a0523a39a19087747e4dafda0362dc867531e3d72a3f195564c84e5e08"
|
||||
checksum = "77e37e62f59cf3284067337da7467d842df8cfe3f5e5c06487ac7521819cf16d"
|
||||
dependencies = [
|
||||
"aws-smithy-async",
|
||||
"aws-smithy-types",
|
||||
"fastrand",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"zeroize",
|
||||
@@ -128,9 +170,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-endpoint"
|
||||
version = "0.54.1"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80a4f935ab6a1919fbfd6102a80c4fccd9ff5f47f94ba154074afe1051903261"
|
||||
checksum = "9f38276d5875b19a9bb2b4ae049fd776c932fcc62068f78b71ce475093ccb4c8"
|
||||
dependencies = [
|
||||
"aws-smithy-http",
|
||||
"aws-smithy-types",
|
||||
@@ -142,9 +184,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-http"
|
||||
version = "0.54.1"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82976ca4e426ee9ca3ffcf919d9b2c8d14d0cd80d43cc02173737a8f07f28d4d"
|
||||
checksum = "67224bfece71e21a63ae82b1ebbfda05be28678a0fab06def03229c7a445d3fb"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-smithy-http",
|
||||
@@ -161,9 +203,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-ec2"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b40ee2d853d8300a49513778beb79b1574ff9e9c94b30b1531bc0171d730ad64"
|
||||
checksum = "fd180c0cb50c9b4306288a9c67f51a0e252ce09f05462b34a437b8b37107982e"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-endpoint",
|
||||
@@ -189,9 +231,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-sso"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca0119bacf0c42f587506769390983223ba834e605f049babe514b2bd646dbb2"
|
||||
checksum = "f4c10657158e12163d6b3fb1e0c9154e43656843794a3071d9ee63ec82a4de2d"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-endpoint",
|
||||
@@ -209,13 +251,14 @@ dependencies = [
|
||||
"regex",
|
||||
"tokio-stream",
|
||||
"tower",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-sdk-sts"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "270b6a33969ebfcb193512fbd5e8ee5306888ad6c6d5d775cdbfb2d50d94de26"
|
||||
checksum = "706a308b7277ac9aac78ab37933509659c6f978a8473e95d8e7a8103093133c3"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-endpoint",
|
||||
@@ -239,9 +282,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sig-auth"
|
||||
version = "0.54.1"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "660a02a98ab1af83bd8d714afbab2d502ba9b18c49e7e4cddd6bf8837ff778cb"
|
||||
checksum = "cebfa0f118afd7197185d5e097bfcdfca9f8410dca50435d67784405f1fd5a05"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-sigv4",
|
||||
@@ -253,9 +296,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-sigv4"
|
||||
version = "0.54.1"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdaf11005b7444e6cd66f600d09861a3aeb6eb89a0f003c7c9820dbab2d15297"
|
||||
checksum = "19a4f5c05c8646d12b7bb3f18c04edc5ac5e8928ab80e1649e568190f2bc7b79"
|
||||
dependencies = [
|
||||
"aws-smithy-http",
|
||||
"form_urlencoded",
|
||||
@@ -272,9 +315,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-async"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63c712a28a4f2f2139759235c08bf98aca99d4fdf1b13c78c5f95613df0a5db9"
|
||||
checksum = "8cd4b9b7d99263f75304fc1fcd752361cbc4cbf068b832acd8daeaaff44267eb"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"pin-project-lite",
|
||||
@@ -284,9 +327,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-client"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "104ca17f56cde00a10207169697dfe9c6810db339d52fb352707e64875b30a44"
|
||||
checksum = "748298b60bbd0594223ea136ceed2ed4b6d50970bcefa69a5ff6d710ce593854"
|
||||
dependencies = [
|
||||
"aws-smithy-async",
|
||||
"aws-smithy-http",
|
||||
@@ -300,6 +343,7 @@ dependencies = [
|
||||
"hyper-rustls",
|
||||
"lazy_static",
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tracing",
|
||||
@@ -307,9 +351,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-http"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "873f316f1833add0d3aa54ed1b0cd252ddd88c792a0cf839886400099971e844"
|
||||
checksum = "d78510732b81040689dc146e3693bfbcf388ab88cbda667d3ef67f8869b0744a"
|
||||
dependencies = [
|
||||
"aws-smithy-types",
|
||||
"bytes",
|
||||
@@ -329,9 +373,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-http-tower"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f38231d3f5dac9ac7976f44e12803add1385119ffca9e5f050d8e980733d164"
|
||||
checksum = "dc33689c27bbd8184412b45c4d1ab795d9a35402562d9fde6c53695a90969740"
|
||||
dependencies = [
|
||||
"aws-smithy-http",
|
||||
"aws-smithy-types",
|
||||
@@ -345,18 +389,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-json"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bd83ff2b79e9f729746fcc8ad798676b68fe6ea72986571569a5306a277a182"
|
||||
checksum = "ada31cab1b1d1f0abc5c4d1183de5b278597704851aa703801b82feabf19aa74"
|
||||
dependencies = [
|
||||
"aws-smithy-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-query"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2f0445dafe9d2cd50b44339ae3c3ed46549aad8ac696c52ad660b3e7ae8682b"
|
||||
checksum = "b55358401b657d192f70f093927f01d73cc4859e2907956b20c4043c76624006"
|
||||
dependencies = [
|
||||
"aws-smithy-types",
|
||||
"urlencoding",
|
||||
@@ -364,9 +408,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-types"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8161232eda10290f5136610a1eb9de56aceaccd70c963a26a260af20ac24794f"
|
||||
checksum = "474d145c2e0f82892841d2502bd546ca0dbc1e4e242c3563d96e7061054c268f"
|
||||
dependencies = [
|
||||
"base64-simd",
|
||||
"itoa",
|
||||
@@ -377,18 +421,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-xml"
|
||||
version = "0.54.4"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "343ffe9a9bb3f542675f4df0e0d5933513d6ad038ca3907ad1767ba690a99684"
|
||||
checksum = "bb159921734d090b01c586a4fef73964f42fcb7eb53a8184b2db374bd6a6fc99"
|
||||
dependencies = [
|
||||
"xmlparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-types"
|
||||
version = "0.54.1"
|
||||
version = "0.55.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8f15b34253b68cde08e39b0627cc6101bcca64351229484b4743392c035d057"
|
||||
checksum = "81fb02591b5075d318e0083dcb76df0e151db4ce48f987ecd00e5b53c7a6ba59"
|
||||
dependencies = [
|
||||
"aws-credential-types",
|
||||
"aws-smithy-async",
|
||||
@@ -676,40 +720,45 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.6"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3"
|
||||
checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"bitflags",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.1.0"
|
||||
version = "4.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
|
||||
checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.2"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
@@ -732,6 +781,21 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concolor-override"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f"
|
||||
|
||||
[[package]]
|
||||
name = "concolor-query"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf"
|
||||
dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
@@ -740,7 +804,7 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "core"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async_timing_util",
|
||||
@@ -758,8 +822,9 @@ dependencies = [
|
||||
"hex",
|
||||
"hmac",
|
||||
"jwt",
|
||||
"merge_config_files",
|
||||
"monitor_helpers",
|
||||
"monitor_types 0.2.10",
|
||||
"monitor_types 0.2.14",
|
||||
"mungos",
|
||||
"periphery_client",
|
||||
"serde",
|
||||
@@ -886,7 +951,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -903,7 +968,7 @@ checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -946,7 +1011,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -960,7 +1025,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -971,7 +1036,7 @@ checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
|
||||
dependencies = [
|
||||
"darling_core 0.13.4",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -982,7 +1047,7 @@ checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
|
||||
dependencies = [
|
||||
"darling_core 0.14.3",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -993,10 +1058,10 @@ checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb"
|
||||
|
||||
[[package]]
|
||||
name = "db_client"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"monitor_types 0.2.10",
|
||||
"monitor_types 0.2.14",
|
||||
"mungos",
|
||||
]
|
||||
|
||||
@@ -1008,7 +1073,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1029,7 +1094,7 @@ dependencies = [
|
||||
"darling 0.14.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1039,7 +1104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1052,7 +1117,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version 0.4.0",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1074,7 +1139,7 @@ checksum = "fe165e7ead196bbbf44c7ce11a7a21157b5c002ce46d7098ff9c556784a4912d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1118,7 +1183,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1256,7 +1321,7 @@ checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1443,9 +1508,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.24"
|
||||
version = "0.14.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c"
|
||||
checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@@ -1768,6 +1833,18 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "merge_config_files"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48ed7c516ae04f732a7651e6bbbbdfd7762170fca6b6d263c14a105c41cab9a5"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
@@ -1857,12 +1934,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "monitor_cli"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"async_timing_util",
|
||||
"clap",
|
||||
"colored",
|
||||
"monitor_types 0.2.10",
|
||||
"monitor_types 0.2.14",
|
||||
"rand",
|
||||
"run_command",
|
||||
"serde",
|
||||
@@ -1874,12 +1951,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "monitor_client"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"envy",
|
||||
"futures-util",
|
||||
"monitor_types 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"monitor_types 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@@ -1891,11 +1968,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "monitor_helpers"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
"monitor_types 0.2.10",
|
||||
"monitor_types 0.2.14",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -1904,7 +1981,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "monitor_periphery"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async_timing_util",
|
||||
@@ -1915,8 +1992,9 @@ dependencies = [
|
||||
"dotenv",
|
||||
"envy",
|
||||
"futures",
|
||||
"merge_config_files",
|
||||
"monitor_helpers",
|
||||
"monitor_types 0.2.10",
|
||||
"monitor_types 0.2.14",
|
||||
"run_command",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@@ -1930,7 +2008,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "monitor_types"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bollard",
|
||||
@@ -1947,9 +2025,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "monitor_types"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bf35db6341431dea9f062f5d676305a213834638410fb9cdc49ca2521635c43"
|
||||
checksum = "19f0b594fa8c0af0c9d4ad7962a15782c7aa4afa575c60df69341f2de012e0c5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bollard",
|
||||
@@ -2122,7 +2200,7 @@ checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2144,12 +2222,6 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "outref"
|
||||
version = "0.5.1"
|
||||
@@ -2196,11 +2268,11 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "periphery_client"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"futures-util",
|
||||
"monitor_types 0.2.10",
|
||||
"monitor_types 0.2.14",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2225,7 +2297,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2252,35 +2324,11 @@ version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.51"
|
||||
version = "1.0.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||
checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -2293,9 +2341,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -2637,7 +2685,7 @@ checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2669,7 +2717,7 @@ checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2727,7 +2775,7 @@ dependencies = [
|
||||
"darling 0.13.4",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2856,7 +2904,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2885,6 +2933,17 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sync_wrapper"
|
||||
version = "0.1.2"
|
||||
@@ -2966,7 +3025,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3050,7 +3109,7 @@ checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3245,7 +3304,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3336,7 +3395,7 @@ checksum = "89851716b67b937e393b3daa8423e67ddfc4bbbf1654bcf05488e95e0828db0c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3364,7 +3423,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc670d0e358428857cc3b4bf504c691e572fccaec9542ff09212d3f13d74b7a9"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3432,6 +3491,12 @@ version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.3.0"
|
||||
@@ -3503,7 +3568,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -3537,7 +3602,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 1.0.109",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "monitor_cli"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
authors = ["MoghTech"]
|
||||
description = "monitor cli | tools to setup monitor system"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "core"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -35,5 +35,6 @@ futures-util = "0.3"
|
||||
diff-struct = "0.5"
|
||||
typeshare = "1.0.0"
|
||||
hex = "0.4"
|
||||
aws-config = "0.54"
|
||||
aws-sdk-ec2 = "0.24"
|
||||
aws-config = "0.55"
|
||||
aws-sdk-ec2 = "0.25"
|
||||
merge_config_files = "0.1.3"
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
use aws_sdk_ec2::Client;
|
||||
use diff::Diff;
|
||||
use helpers::{all_logs_success, to_monitor_name};
|
||||
use mungos::{doc, to_bson};
|
||||
@@ -14,7 +15,7 @@ use types::{
|
||||
use crate::{
|
||||
auth::RequestUser,
|
||||
cloud::aws::{
|
||||
self, create_ec2_client, create_instance_with_ami, terminate_ec2_instance, Ec2Instance,
|
||||
create_ec2_client, create_instance_with_ami, terminate_ec2_instance, Ec2Instance,
|
||||
},
|
||||
helpers::empty_or_only_spaces,
|
||||
state::State,
|
||||
@@ -426,7 +427,7 @@ impl State {
|
||||
async fn create_ec2_instance_for_build(
|
||||
&self,
|
||||
build: &Build,
|
||||
) -> anyhow::Result<(Ec2Instance, Option<aws::Client>, Vec<Log>)> {
|
||||
) -> anyhow::Result<(Ec2Instance, Option<Client>, Vec<Log>)> {
|
||||
if build.aws_config.is_none() {
|
||||
return Err(anyhow!("build has no aws_config attached"));
|
||||
}
|
||||
@@ -527,7 +528,7 @@ impl State {
|
||||
|
||||
async fn terminate_ec2_instance(
|
||||
&self,
|
||||
aws_client: aws::Client,
|
||||
aws_client: Client,
|
||||
server: &Ec2Instance,
|
||||
update: &mut Update,
|
||||
) {
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
state::{State, StateExtension},
|
||||
};
|
||||
|
||||
const NUM_UPDATES_PER_PAGE: usize = 10;
|
||||
const NUM_UPDATES_PER_PAGE: usize = 20;
|
||||
|
||||
pub fn router() -> Router {
|
||||
Router::new().route(
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
use aws_sdk_ec2::model::{
|
||||
BlockDeviceMapping, EbsBlockDevice, InstanceNetworkInterfaceSpecification, InstanceStateChange,
|
||||
InstanceStateName, InstanceStatus, ResourceType, Tag, TagSpecification,
|
||||
};
|
||||
pub use aws_sdk_ec2::{
|
||||
model::InstanceType,
|
||||
output::{DescribeInstanceStatusOutput, TerminateInstancesOutput},
|
||||
Client, Region,
|
||||
use aws_sdk_ec2::{
|
||||
config::Region,
|
||||
types::{
|
||||
BlockDeviceMapping, EbsBlockDevice, InstanceNetworkInterfaceSpecification,
|
||||
InstanceStateChange, InstanceStateName, InstanceStatus, InstanceType, ResourceType, Tag,
|
||||
TagSpecification,
|
||||
},
|
||||
Client,
|
||||
};
|
||||
use types::Server;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use axum_extra::routing::SpaRouter;
|
||||
use dotenv::dotenv;
|
||||
use helpers::parse_config_file;
|
||||
use merge_config_files::parse_config_file;
|
||||
use mungos::Deserialize;
|
||||
use types::CoreConfig;
|
||||
|
||||
@@ -15,7 +15,7 @@ struct Env {
|
||||
pub fn load() -> (CoreConfig, SpaRouter) {
|
||||
dotenv().ok();
|
||||
let env: Env = envy::from_env().expect("failed to parse environment variables");
|
||||
let config = parse_config_file(&env.config_path).expect("failed to parse config");
|
||||
let config = parse_config_file(env.config_path).expect("failed to parse config");
|
||||
let spa_router = SpaRouter::new("/assets", env.frontend_path);
|
||||
(config, spa_router)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ The easiest way to do this is to follow the [monitor guide](https://github.com/m
|
||||
|
||||
1. Download the periphery binary from the latest [release](https://github.com/mbecker20/monitor/releases).
|
||||
|
||||
2. Create and edit your config files, following the [config example](https://github.com/mbecker20/monitor/blob/main/config_example/periphery.config.example.toml). The monitor cli can be used to add the boilerplate: ```monitor periphery gen-config --path /path/to/config.toml```. The files can be anywhere, and can be passed to periphery via the ```--config-path``` flag.
|
||||
2. Create and edit your config files, following the [config example](https://github.com/mbecker20/monitor/blob/main/config_example/periphery.config.example.toml). The monitor cli can be used to add the boilerplate: ```monitor periphery gen-config --path /path/to/config.toml```. The files can be anywhere, and can be passed to periphery via the ```--config-path``` argument.
|
||||
|
||||
3. Ensure that inbound connectivity is allowed on the port specified in periphery.config.toml (default 8000).
|
||||
|
||||
@@ -26,16 +26,22 @@ The easiest way to do this is to follow the [monitor guide](https://github.com/m
|
||||
```
|
||||
periphery \
|
||||
--config-path /path/to/periphery.config.base.toml \
|
||||
--config-path /other_path/to/periphery.config.overide.toml \
|
||||
--config-path /other_path/to/overide-periphery-config-directory \
|
||||
--config-keyword periphery \
|
||||
--config-keyword config \
|
||||
--merge-nested-config \
|
||||
--home_dir /home/username
|
||||
```
|
||||
|
||||
## passing config files
|
||||
|
||||
when you pass multiple config files, later --config-path given in the command will always overide previous ones.
|
||||
Either file paths or directory paths can be passed to ```--config-path```.
|
||||
|
||||
there are two ways to merge config files. The default behavior is to completely replace any base fields with whatever fields are present in the overide config. So if you pass ```allowed_ips = []``` in your overide config, the final allowed_ips will be an empty list as well.
|
||||
When using directories, the file entries can be filtered by name with the ```--config-keyword``` argument, which can be passed multiple times to add more keywords. If passed, then only config files with file names that contain all keywords will be merged.
|
||||
|
||||
When passing multiple config files, later --config-path given in the command will always overide previous ones. Directory config files are merged in alphabetical order by name, so ```config_b.toml``` will overide ```config_a.toml```.
|
||||
|
||||
There are two ways to merge config files. The default behavior is to completely replace any base fields with whatever fields are present in the overide config. So if you pass ```allowed_ips = []``` in your overide config, the final allowed_ips will be an empty list as well.
|
||||
|
||||
```--merge-nested-config``` will merge config fields recursively and extend config array fields.
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ const Users = lazy(() => import("./components/users/Users"));
|
||||
const User = lazy(() => import("./components/users/User"));
|
||||
const Stats = lazy(() => import("./components/stats/Stats"));
|
||||
const Account = lazy(() => import("./components/account/Account"));
|
||||
const Updates = lazy(() => import("./components/Updates"));
|
||||
|
||||
const App: Component = () => {
|
||||
const { user } = useUser();
|
||||
@@ -19,6 +20,7 @@ const App: Component = () => {
|
||||
<Topbar />
|
||||
<Routes>
|
||||
<Route path="/" component={Home} />
|
||||
<Route path="/updates" component={Updates} />
|
||||
<Route path="/build/:id" component={Build} />
|
||||
<Route path="/deployment/:id" component={Deployment} />
|
||||
<Route path="/server/:id" component={Server} />
|
||||
|
||||
@@ -69,10 +69,10 @@ const CopyMenu: Component<{
|
||||
targetClass="blue"
|
||||
content={() => (
|
||||
<Grid placeItems="center">
|
||||
<Flex alignItems="center">
|
||||
<Flex class="full-width" alignItems="center">
|
||||
<Input
|
||||
placeholder="copy name"
|
||||
class="card dark"
|
||||
class="card dark full-width"
|
||||
style={{ padding: "0.5rem" }}
|
||||
value={newName()}
|
||||
onEdit={setNewName}
|
||||
@@ -87,6 +87,8 @@ const CopyMenu: Component<{
|
||||
targetClass="blue"
|
||||
targetStyle={{ display: "flex", gap: "0.5rem" }}
|
||||
searchStyle={{ width: "100%" }}
|
||||
menuClass="scroller"
|
||||
menuStyle={{ "max-height": "40vh" }}
|
||||
position="bottom right"
|
||||
useSearch
|
||||
/>
|
||||
|
||||
157
frontend/src/components/Updates.tsx
Normal file
157
frontend/src/components/Updates.tsx
Normal file
@@ -0,0 +1,157 @@
|
||||
import { A } from "@solidjs/router";
|
||||
import {
|
||||
Component,
|
||||
createEffect,
|
||||
createMemo,
|
||||
createSignal,
|
||||
For,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { OPERATIONS } from "..";
|
||||
import { useAppDimensions } from "../state/DimensionProvider";
|
||||
import { useAppState } from "../state/StateProvider";
|
||||
import { Operation, Update as UpdateType, UpdateStatus } from "../types";
|
||||
import { readableMonitorTimestamp, readableVersion } from "../util/helpers";
|
||||
import Icon from "./shared/Icon";
|
||||
import Input from "./shared/Input";
|
||||
import Flex from "./shared/layout/Flex";
|
||||
import Grid from "./shared/layout/Grid";
|
||||
import Loading from "./shared/loading/Loading";
|
||||
import Selector from "./shared/menu/Selector";
|
||||
import UpdateMenu from "./update/UpdateMenu";
|
||||
|
||||
const Updates: Component<{}> = (p) => {
|
||||
const { isMobile } = useAppDimensions();
|
||||
const { updates, usernames, name_from_update_target } = useAppState();
|
||||
const [operation, setOperation] = createSignal<Operation>();
|
||||
createEffect(() => {
|
||||
if (operation()) {
|
||||
updates.load([operation()!]);
|
||||
} else {
|
||||
updates.load();
|
||||
}
|
||||
});
|
||||
const [search, setSearch] = createSignal("");
|
||||
const filtered_updates = createMemo(() => {
|
||||
return updates.collection()?.filter((u) => {
|
||||
const name = name_from_update_target(u.target);
|
||||
if (name.includes(search())) return true;
|
||||
const username = usernames.get(u.operator);
|
||||
if (username?.includes(search())) return true;
|
||||
});
|
||||
});
|
||||
return (
|
||||
<Grid class="full-width card shadow">
|
||||
<Flex alignItems="center" justifyContent="space-between">
|
||||
<h1>updates</h1>
|
||||
<Flex alignItems="center">
|
||||
<Input class="lightgrey" placeholder="search" onEdit={setSearch} />
|
||||
<Selector
|
||||
label={isMobile() ? undefined : "operation: "}
|
||||
selected={operation() ? operation()! : "all"}
|
||||
items={["all", ...OPERATIONS]}
|
||||
onSelect={(o) =>
|
||||
o === "all"
|
||||
? setOperation(undefined)
|
||||
: setOperation(o.replaceAll(" ", "_") as Operation)
|
||||
}
|
||||
targetClass="blue"
|
||||
position="bottom right"
|
||||
searchStyle={{ width: "15rem" }}
|
||||
menuClass="scroller"
|
||||
menuStyle={{ "max-height": "50vh" }}
|
||||
useSearch
|
||||
/>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Show
|
||||
when={updates.loaded()}
|
||||
fallback={
|
||||
<Flex justifyContent="center">
|
||||
<Loading type="three-dot" />
|
||||
</Flex>
|
||||
}
|
||||
>
|
||||
<For each={filtered_updates()}>
|
||||
{(update) => <Update update={update} />}
|
||||
</For>
|
||||
<Show when={!updates.noMore()}>
|
||||
<button
|
||||
class="grey full-width"
|
||||
onClick={() =>
|
||||
operation()
|
||||
? updates.loadMore([operation()!])
|
||||
: updates.loadMore()
|
||||
}
|
||||
>
|
||||
load more
|
||||
</button>
|
||||
</Show>
|
||||
</Show>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default Updates;
|
||||
|
||||
const Update: Component<{ update: UpdateType }> = (p) => {
|
||||
const { isMobile } = useAppDimensions();
|
||||
const { usernames, name_from_update_target } = useAppState();
|
||||
const name = () => name_from_update_target(p.update.target);
|
||||
const operation = () => {
|
||||
if (p.update.operation === Operation.BuildBuild) {
|
||||
return `build ${readableVersion(p.update.version!)}`;
|
||||
}
|
||||
return `${p.update.operation.replaceAll("_", " ")}${
|
||||
p.update.version ? " " + readableVersion(p.update.version) : ""
|
||||
}`;
|
||||
};
|
||||
const link_to = () => {
|
||||
return p.update.target.type === "System"
|
||||
? "/"
|
||||
: `/${p.update.target.type.toLowerCase()}/${p.update.target.id}`;
|
||||
};
|
||||
return (
|
||||
<Flex
|
||||
class="card light shadow wrap"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<Flex
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
style={{ width: isMobile() ? "100%" : undefined }}
|
||||
>
|
||||
<A style={{ padding: 0 }} href={link_to()}>
|
||||
<h2 class="text-hover">{name()}</h2>
|
||||
</A>
|
||||
<div
|
||||
style={{
|
||||
color: !p.update.success ? "rgb(182, 47, 52)" : "inherit",
|
||||
}}
|
||||
>
|
||||
{operation()}
|
||||
</div>
|
||||
<Show when={p.update.status === UpdateStatus.InProgress}>
|
||||
<div style={{ opacity: 0.7 }}>(in progress)</div>
|
||||
</Show>
|
||||
</Flex>
|
||||
<Flex
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
style={{ width: isMobile() ? "100%" : undefined }}
|
||||
>
|
||||
<Flex gap="0.5rem">
|
||||
<Icon type="user" />
|
||||
<div>{usernames.get(p.update.operator)}</div>
|
||||
</Flex>
|
||||
<Flex alignItems="center">
|
||||
<div style={{ "place-self": "center end" }}>
|
||||
{readableMonitorTimestamp(p.update.start_ts)}
|
||||
</div>
|
||||
<UpdateMenu update={p.update} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -11,6 +11,8 @@ import BuildArgs from "./BuildArgs";
|
||||
import Version from "./Version";
|
||||
import Repo from "./Repo";
|
||||
import WebhookUrl from "./WebhookUrl";
|
||||
import ExtraArgs from "./ExtraArgs";
|
||||
import UseBuildx from "./UseBuildx";
|
||||
|
||||
const BuildConfig: Component<{}> = (p) => {
|
||||
const { build, reset, save, userCanUpdate } = useConfig();
|
||||
@@ -23,6 +25,8 @@ const BuildConfig: Component<{}> = (p) => {
|
||||
<Docker />
|
||||
<CliBuild />
|
||||
<BuildArgs />
|
||||
<ExtraArgs />
|
||||
<UseBuildx />
|
||||
<Show when={userCanUpdate()}>
|
||||
<WebhookUrl />
|
||||
</Show>
|
||||
|
||||
59
frontend/src/components/build/tabs/config/ExtraArgs.tsx
Normal file
59
frontend/src/components/build/tabs/config/ExtraArgs.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Component, For, Show } from "solid-js";
|
||||
import Icon from "../../../shared/Icon";
|
||||
import Input from "../../../shared/Input";
|
||||
import Flex from "../../../shared/layout/Flex";
|
||||
import Grid from "../../../shared/layout/Grid";
|
||||
import { useConfig } from "../Provider";
|
||||
|
||||
const ExtraArgs: Component<{}> = (p) => {
|
||||
const { build, setBuild, userCanUpdate } = useConfig();
|
||||
const onAdd = () => {
|
||||
setBuild("docker_build_args", "extra_args", (extra_args: any) => [
|
||||
...extra_args,
|
||||
"",
|
||||
]);
|
||||
};
|
||||
const onRemove = (index: number) => {
|
||||
setBuild("docker_build_args", "extra_args", (extra_args) =>
|
||||
extra_args!.filter((_, i) => i !== index)
|
||||
);
|
||||
};
|
||||
return (
|
||||
<Grid class="config-item shadow">
|
||||
<Flex justifyContent="space-between" alignItems="center">
|
||||
<h1>extra args</h1>
|
||||
<Show when={userCanUpdate()}>
|
||||
<button class="green" onClick={onAdd}>
|
||||
<Icon type="plus" />
|
||||
</button>
|
||||
</Show>
|
||||
</Flex>
|
||||
<For each={[...build.docker_build_args!.extra_args!.keys()]}>
|
||||
{(_, index) => (
|
||||
<Flex
|
||||
justifyContent={userCanUpdate() ? "space-between" : undefined}
|
||||
alignItems="center"
|
||||
style={{ "flex-wrap": "wrap" }}
|
||||
>
|
||||
<Input
|
||||
placeholder="--extra-arg=value"
|
||||
value={build.docker_build_args!.extra_args![index()]}
|
||||
style={{ width: "80%" }}
|
||||
onEdit={(value) =>
|
||||
setBuild("docker_build_args", "extra_args", index(), value)
|
||||
}
|
||||
disabled={!userCanUpdate()}
|
||||
/>
|
||||
<Show when={userCanUpdate()}>
|
||||
<button class="red" onClick={() => onRemove(index())}>
|
||||
<Icon type="minus" />
|
||||
</button>
|
||||
</Show>
|
||||
</Flex>
|
||||
)}
|
||||
</For>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default ExtraArgs;
|
||||
30
frontend/src/components/build/tabs/config/UseBuildx.tsx
Normal file
30
frontend/src/components/build/tabs/config/UseBuildx.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import { Component, Show } from "solid-js";
|
||||
import Flex from "../../../shared/layout/Flex";
|
||||
import { useConfig } from "../Provider";
|
||||
|
||||
const UseBuildx: Component<{}> = (p) => {
|
||||
const { build, setBuild, userCanUpdate } = useConfig();
|
||||
const use_buildx = () => build.docker_build_args?.use_buildx || false;
|
||||
return (
|
||||
<Flex
|
||||
class="config-item shadow"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<h1>use buildx</h1>
|
||||
<Show
|
||||
when={userCanUpdate()}
|
||||
fallback={<div>{use_buildx() ? "enabled" : "disabled"}</div>}
|
||||
>
|
||||
<button
|
||||
class={use_buildx() ? "green" : "red"}
|
||||
onClick={() => setBuild("docker_build_args", "use_buildx", (c) => !c)}
|
||||
>
|
||||
{use_buildx() ? "enabled" : "disabled"}
|
||||
</button>
|
||||
</Show>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default UseBuildx;
|
||||
@@ -119,7 +119,18 @@ const Header: Component<{}> = (p) => {
|
||||
/>
|
||||
</Show>
|
||||
</Show>
|
||||
<div style={{ opacity: 0.7 }}>{image()}</div>
|
||||
<Show
|
||||
when={deployment().deployment.build_id}
|
||||
fallback={<div style={{ opacity: 0.7 }}>{image()}</div>}
|
||||
>
|
||||
<A
|
||||
href={`/build/${deployment().deployment.build_id}`}
|
||||
class="text-hover"
|
||||
style={{ opacity: 0.7, padding: 0 }}
|
||||
>
|
||||
{image()}
|
||||
</A>
|
||||
</Show>
|
||||
</Flex>
|
||||
<Show when={userCanUpdate()}>
|
||||
<Flex alignItems="center">
|
||||
|
||||
@@ -14,26 +14,29 @@ const Summary: Component<{}> = (p) => {
|
||||
const serverCount = useServerCount();
|
||||
return (
|
||||
<Grid
|
||||
class="card shadow"
|
||||
class="full-size"
|
||||
gridTemplateColumns={isMobile() ? "1fr" : "1fr 1fr"}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
"box-sizing": "border-box",
|
||||
}}
|
||||
placeItems="center"
|
||||
gap="0"
|
||||
>
|
||||
<div
|
||||
style={{ width: `${PIE_CHART_SIZE}px`, height: `${PIE_CHART_SIZE}px` }}
|
||||
>
|
||||
<PieChart title="deployments" sections={deployentCount()} />
|
||||
</div>
|
||||
<div
|
||||
style={{ width: `${PIE_CHART_SIZE}px`, height: `${PIE_CHART_SIZE}px` }}
|
||||
>
|
||||
<PieChart title="servers" sections={serverCount()} />
|
||||
</div>
|
||||
<Grid class="card shadow full-size" placeItems="center">
|
||||
<div
|
||||
style={{
|
||||
width: `${PIE_CHART_SIZE}px`,
|
||||
height: `${PIE_CHART_SIZE}px`,
|
||||
}}
|
||||
>
|
||||
<PieChart title="deployments" sections={deployentCount()} />
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid class="card shadow full-size" placeItems="center">
|
||||
<div
|
||||
style={{
|
||||
width: `${PIE_CHART_SIZE}px`,
|
||||
height: `${PIE_CHART_SIZE}px`,
|
||||
}}
|
||||
>
|
||||
<PieChart title="servers" sections={serverCount()} />
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
import { Component, createMemo, For, Show } from "solid-js";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
import { DockerContainerState, ServerStatus } from "../../types";
|
||||
import Grid from "../shared/layout/Grid";
|
||||
import Flex from "../shared/layout/Flex";
|
||||
|
||||
const Summary: Component<{}> = (p) => {
|
||||
return (
|
||||
<Grid class="card shadow" gridTemplateRows="auto 1fr 1fr 1fr">
|
||||
<h1>summary</h1>
|
||||
<DeploymentsSummary />
|
||||
<ServersSummary />
|
||||
<BuildsSummary />
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default Summary;
|
||||
|
||||
const SummaryItem: Component<{
|
||||
title: string;
|
||||
metrics: Array<{ title: string; class: string; count?: number }>;
|
||||
}> = (p) => {
|
||||
return (
|
||||
<Flex
|
||||
class="card light shadow wrap"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
>
|
||||
<h2>{p.title}</h2>
|
||||
<Flex class="wrap">
|
||||
<For each={p.metrics}>
|
||||
{(metric) => (
|
||||
<Show when={metric?.count && metric.count > 0}>
|
||||
<Flex gap="0.4rem" alignItems="center">
|
||||
<div>{metric.title}</div>
|
||||
<h2 class={metric.class}>{metric.count}</h2>
|
||||
</Flex>
|
||||
</Show>
|
||||
)}
|
||||
</For>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const BuildsSummary = () => {
|
||||
const { builds } = useAppState();
|
||||
return (
|
||||
<SummaryItem
|
||||
title="builds"
|
||||
metrics={[
|
||||
{ title: "total", class: "text-green", count: builds.ids()?.length },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const DeploymentsSummary = () => {
|
||||
const deployentCount = useDeploymentCount();
|
||||
return (
|
||||
<SummaryItem
|
||||
title="deployments"
|
||||
metrics={[
|
||||
{
|
||||
title: "total",
|
||||
class: "text-green",
|
||||
count: deployentCount().total,
|
||||
},
|
||||
{
|
||||
title: "running",
|
||||
class: "text-green",
|
||||
count: deployentCount().running,
|
||||
},
|
||||
{
|
||||
title: "stopped",
|
||||
class: "text-red",
|
||||
count: deployentCount().stopped,
|
||||
},
|
||||
{
|
||||
title: "not deployed",
|
||||
class: "text-blue",
|
||||
count: deployentCount().notDeployed,
|
||||
},
|
||||
{
|
||||
title: "unknown",
|
||||
class: "text-blue",
|
||||
count: deployentCount().unknown,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const ServersSummary = () => {
|
||||
const serverCount = useServerCount();
|
||||
return (
|
||||
<SummaryItem
|
||||
title="servers"
|
||||
metrics={[
|
||||
{ title: "total", class: "text-green", count: serverCount().total },
|
||||
{ title: "healthy", class: "text-green", count: serverCount().healthy },
|
||||
{
|
||||
title: "unhealthy",
|
||||
class: "text-red",
|
||||
count: serverCount().unhealthy,
|
||||
},
|
||||
{
|
||||
title: "disabled",
|
||||
class: "text-blue",
|
||||
count: serverCount().disabled,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
function useDeploymentCount() {
|
||||
const { deployments } = useAppState();
|
||||
const count = createMemo(() => {
|
||||
const ids = deployments.ids();
|
||||
if (!ids)
|
||||
return { total: 0, running: 0, stopped: 0, notDeployed: 0, unknown: 0 };
|
||||
let running = 0;
|
||||
let stopped = 0;
|
||||
let notDeployed = 0;
|
||||
let unknown = 0;
|
||||
for (const id of ids) {
|
||||
const state = deployments.get(id)!.state;
|
||||
if (state === DockerContainerState.NotDeployed) {
|
||||
notDeployed++;
|
||||
} else if (state === DockerContainerState.Running) {
|
||||
running++;
|
||||
} else if (state === DockerContainerState.Exited) {
|
||||
stopped++;
|
||||
} else if (state === DockerContainerState.Unknown) {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
return { total: ids.length, running, stopped, notDeployed, unknown };
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
function useServerCount() {
|
||||
const { servers } = useAppState();
|
||||
const count = createMemo(() => {
|
||||
const ids = servers.ids();
|
||||
if (!ids) return { total: 0, healthy: 0, unhealthy: 0, disabled: 0 };
|
||||
let healthy = 0;
|
||||
let unhealthy = 0;
|
||||
let disabled = 0;
|
||||
for (const id of ids) {
|
||||
const server = servers.get(id)!;
|
||||
if (server.status === ServerStatus.Disabled) {
|
||||
disabled++;
|
||||
} else if (server.status === ServerStatus.Ok) {
|
||||
healthy++;
|
||||
} else if (server.status === ServerStatus.NotOk) {
|
||||
unhealthy++;
|
||||
}
|
||||
}
|
||||
return { total: ids.length, healthy, unhealthy, disabled };
|
||||
});
|
||||
return count;
|
||||
}
|
||||
@@ -14,18 +14,9 @@ import UpdateMenu from "../../update/UpdateMenu";
|
||||
import s from "./update.module.scss";
|
||||
|
||||
const Update: Component<{ update: UpdateType }> = (p) => {
|
||||
const { deployments, servers, builds, usernames } = useAppState();
|
||||
const name = () => {
|
||||
if (p.update.target.type === "Deployment" && deployments.loaded()) {
|
||||
return deployments.get(p.update.target.id!)?.deployment.name || "deleted";
|
||||
} else if (p.update.target.type === "Server" && servers.loaded()) {
|
||||
return servers.get(p.update.target.id)?.server.name || "deleted";
|
||||
} else if (p.update.target.type === "Build" && builds.loaded()) {
|
||||
return builds.get(p.update.target.id)?.name || "deleted";
|
||||
} else {
|
||||
return "monitor";
|
||||
}
|
||||
};
|
||||
const { usernames, name_from_update_target } =
|
||||
useAppState();
|
||||
const name = () => name_from_update_target(p.update.target);
|
||||
const operation = () => {
|
||||
if (p.update.operation === Operation.BuildBuild) {
|
||||
return `build ${readableVersion(p.update.version!)}`;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { A } from "@solidjs/router";
|
||||
import { Component, createEffect, createSignal, For, Show } from "solid-js";
|
||||
import { OPERATIONS } from "../../..";
|
||||
import { useAppState } from "../../../state/StateProvider";
|
||||
import { Operation } from "../../../types";
|
||||
import Flex from "../../shared/layout/Flex";
|
||||
@@ -7,10 +9,6 @@ import Loading from "../../shared/loading/Loading";
|
||||
import Selector from "../../shared/menu/Selector";
|
||||
import Update from "./Update";
|
||||
|
||||
const OPERATIONS = Object.values(Operation)
|
||||
.filter((e) => e !== "none" && !e.includes("user"))
|
||||
.map((e) => e.replaceAll("_", " "));
|
||||
|
||||
const Updates: Component<{}> = () => {
|
||||
const { updates } = useAppState();
|
||||
const [operation, setOperation] = createSignal<Operation>();
|
||||
@@ -24,8 +22,11 @@ const Updates: Component<{}> = () => {
|
||||
return (
|
||||
<Grid class="card shadow" style={{ "flex-grow": 1 }}>
|
||||
<Flex alignItems="center" justifyContent="space-between">
|
||||
<h1>updates</h1>
|
||||
<A href="/updates" style={{ padding: 0 }}>
|
||||
<h1>updates</h1>
|
||||
</A>
|
||||
<Selector
|
||||
label="operation: "
|
||||
selected={operation() ? operation()! : "all"}
|
||||
items={["all", ...OPERATIONS]}
|
||||
onSelect={(o) =>
|
||||
@@ -50,7 +51,7 @@ const Updates: Component<{}> = () => {
|
||||
}
|
||||
>
|
||||
<Grid class="updates-container-small scroller">
|
||||
<For each={updates.collection()!}>
|
||||
<For each={updates.collection()}>
|
||||
{(update) => <Update update={update} />}
|
||||
</For>
|
||||
<Show when={!updates.noMore()}>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { readableStorageAmount } from "../../../util/helpers";
|
||||
import Flex from "../../shared/layout/Flex";
|
||||
import Grid from "../../shared/layout/Grid";
|
||||
import Loading from "../../shared/loading/Loading";
|
||||
import HoverMenu from "../../shared/menu/HoverMenu";
|
||||
|
||||
const Info: Component<{}> = (p) => {
|
||||
const { isMobile } = useAppDimensions();
|
||||
|
||||
@@ -76,7 +76,7 @@ const Child: Component<{
|
||||
>
|
||||
<Grid
|
||||
class={combineClasses(s.Menu, "shadow")}
|
||||
style={{ padding: (p.padding as any) || "1rem", ...p.style }}
|
||||
style={{ padding: (p.padding as any) || "2rem", ...p.style }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onPointerDown={(e) => e.stopPropagation()}
|
||||
>
|
||||
|
||||
@@ -37,10 +37,10 @@ const Selector: Component<{
|
||||
}> = (p) => {
|
||||
const [show, toggle] = useToggle();
|
||||
const [search, setSearch] = createSignal("");
|
||||
let ref: HTMLInputElement | undefined;
|
||||
let search_ref: HTMLInputElement | undefined;
|
||||
const current = () => (p.itemMap ? p.itemMap(p.selected) : p.selected);
|
||||
createEffect(() => {
|
||||
if (show()) setTimeout(() => ref?.focus(), 200);
|
||||
if (show()) setTimeout(() => search_ref?.focus(), 200);
|
||||
});
|
||||
return (
|
||||
<Show
|
||||
@@ -70,7 +70,7 @@ const Selector: Component<{
|
||||
<>
|
||||
<Show when={p.useSearch}>
|
||||
<Input
|
||||
ref={ref}
|
||||
ref={search_ref}
|
||||
placeholder="search"
|
||||
value={search()}
|
||||
onEdit={setSearch}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
width: fit-content;
|
||||
/* border: solid 1px rgba(2, 107, 121, 0.25); */
|
||||
background-color: c.$grey;
|
||||
border: solid c.$darkgrey 2px;
|
||||
z-index: 21;
|
||||
border-radius: 0.25rem;
|
||||
box-sizing: border-box;
|
||||
@@ -142,6 +143,11 @@ $anim-time: 350ms;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.CenterMenuHeader {
|
||||
border-bottom: solid rgba(c.$lightgrey, 0.9) 2px;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.SelectorItem:hover {
|
||||
background-color: c.$lightgrey;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
.TabTitle {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 0.25rem 0.5rem;
|
||||
padding: 0.75rem;
|
||||
border-radius: 0rem;
|
||||
cursor: pointer;
|
||||
font-size: 1rem;
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
import { Accessor, Component, For, ParentComponent, Show } from "solid-js";
|
||||
import {
|
||||
Accessor,
|
||||
Component,
|
||||
For,
|
||||
JSXElement,
|
||||
ParentComponent,
|
||||
Show,
|
||||
} from "solid-js";
|
||||
import { COLORS } from "../../style/colors";
|
||||
import { SystemStats, SystemStatsRecord } from "../../types";
|
||||
import {
|
||||
convertTsMsToLocalUnixTsInSecs,
|
||||
get_to_one_sec_divisor,
|
||||
} from "../../util/helpers";
|
||||
import { useLocalStorage, useLocalStorageToggle } from "../../util/hooks";
|
||||
import Flex from "../shared/layout/Flex";
|
||||
import Grid from "../shared/layout/Grid";
|
||||
import LightweightChart, { LightweightValue } from "../shared/LightweightChart";
|
||||
import s from "./stats.module.scss";
|
||||
@@ -15,13 +24,18 @@ const SMALL_CHART_HEIGHT = "150px";
|
||||
const SingleStatChart: Component<{
|
||||
line?: LightweightValue[];
|
||||
header: string;
|
||||
headerRight?: JSXElement;
|
||||
label: string;
|
||||
color: string;
|
||||
small?: boolean;
|
||||
disableScroll?: boolean;
|
||||
}> = (p) => {
|
||||
return (
|
||||
<StatChartContainer header={p.header} small={p.small}>
|
||||
<StatChartContainer
|
||||
header={p.header}
|
||||
headerRight={p.headerRight}
|
||||
small={p.small}
|
||||
>
|
||||
<Show when={p.line}>
|
||||
<LightweightChart
|
||||
class={s.LightweightChart}
|
||||
@@ -44,23 +58,25 @@ const SingleStatChart: Component<{
|
||||
|
||||
const StatChartContainer: ParentComponent<{
|
||||
header: string;
|
||||
headerRight?: JSXElement;
|
||||
small?: boolean;
|
||||
}> = (p) => {
|
||||
return (
|
||||
<Grid
|
||||
gap="0.5rem"
|
||||
class="card shadow"
|
||||
class="card shadow full-width"
|
||||
style={{
|
||||
height: "fit-content",
|
||||
width: "100%",
|
||||
"box-sizing": "border-box",
|
||||
"padding-top": "0.5rem",
|
||||
"padding-bottom": "0.2rem",
|
||||
}}
|
||||
>
|
||||
<Show when={!p.small} fallback={<div>{p.header}</div>}>
|
||||
<h2>{p.header}</h2>
|
||||
</Show>
|
||||
<Flex justifyContent="space-between">
|
||||
<Show when={!p.small} fallback={<div>{p.header}</div>}>
|
||||
<h2>{p.header}</h2>
|
||||
</Show>
|
||||
{p.headerRight}
|
||||
</Flex>
|
||||
{p.children}
|
||||
</Grid>
|
||||
);
|
||||
@@ -152,20 +168,42 @@ export const MemChart: Component<{
|
||||
small?: boolean;
|
||||
disableScroll?: boolean;
|
||||
}> = (p) => {
|
||||
const [absolute, toggleAbsolute] = useLocalStorageToggle("stats-mem-mode-v2");
|
||||
const symbol = () => (absolute() ? "GiB" : "%");
|
||||
const line = () => {
|
||||
return p.stats()?.map((s) => {
|
||||
return {
|
||||
time: convertTsMsToLocalUnixTsInSecs(
|
||||
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
|
||||
),
|
||||
value: (100 * s.mem_used_gb) / s.mem_total_gb,
|
||||
};
|
||||
});
|
||||
if (absolute()) {
|
||||
return p.stats()?.map((s) => {
|
||||
return {
|
||||
time: convertTsMsToLocalUnixTsInSecs(
|
||||
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
|
||||
),
|
||||
value: s.mem_used_gb,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
return p.stats()?.map((s) => {
|
||||
return {
|
||||
time: convertTsMsToLocalUnixTsInSecs(
|
||||
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
|
||||
),
|
||||
value: (100 * s.mem_used_gb) / s.mem_total_gb,
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<SingleStatChart
|
||||
header="memory"
|
||||
label="mem %"
|
||||
headerRight={
|
||||
<button
|
||||
class="green"
|
||||
style={{ padding: "0.2rem" }}
|
||||
onClick={toggleAbsolute}
|
||||
>
|
||||
{symbol()}
|
||||
</button>
|
||||
}
|
||||
label={`mem ${symbol()}`}
|
||||
color={COLORS.green}
|
||||
line={line()}
|
||||
small={p.small}
|
||||
@@ -179,20 +217,43 @@ export const DiskChart: Component<{
|
||||
small?: boolean;
|
||||
disableScroll?: boolean;
|
||||
}> = (p) => {
|
||||
const [absolute, toggleAbsolute] =
|
||||
useLocalStorageToggle("stats-disk-mode-v2");
|
||||
const symbol = () => (absolute() ? "GiB" : "%");
|
||||
const line = () => {
|
||||
return p.stats()?.map((s) => {
|
||||
return {
|
||||
time: convertTsMsToLocalUnixTsInSecs(
|
||||
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
|
||||
),
|
||||
value: (100 * s.disk.used_gb) / s.disk.total_gb,
|
||||
};
|
||||
});
|
||||
if (absolute()) {
|
||||
return p.stats()?.map((s) => {
|
||||
return {
|
||||
time: convertTsMsToLocalUnixTsInSecs(
|
||||
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
|
||||
),
|
||||
value: s.disk.used_gb,
|
||||
};
|
||||
});
|
||||
} else {
|
||||
return p.stats()?.map((s) => {
|
||||
return {
|
||||
time: convertTsMsToLocalUnixTsInSecs(
|
||||
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
|
||||
),
|
||||
value: (100 * s.disk.used_gb) / s.disk.total_gb,
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<SingleStatChart
|
||||
header="disk"
|
||||
label="disk %"
|
||||
headerRight={
|
||||
<button
|
||||
class="orange"
|
||||
style={{ padding: "0.2rem" }}
|
||||
onClick={toggleAbsolute}
|
||||
>
|
||||
{symbol()}
|
||||
</button>
|
||||
}
|
||||
label={`disk ${symbol()}`}
|
||||
color={COLORS.orange}
|
||||
line={line()}
|
||||
small={p.small}
|
||||
|
||||
@@ -29,20 +29,23 @@ const HistoricalStats: Component<{
|
||||
const params = useParams();
|
||||
const { timelength, page } = useStatsState();
|
||||
const [stats, setStats] = createSignal<SystemStatsRecord[]>();
|
||||
createEffect(() => {
|
||||
client
|
||||
const [loading, setLoading] = createSignal(false);
|
||||
createEffect(async () => {
|
||||
setLoading(true);
|
||||
const stats = await client
|
||||
.get_server_stats_history(params.id, {
|
||||
interval: timelength(),
|
||||
page: page(),
|
||||
limit: 500,
|
||||
networks: true,
|
||||
components: true,
|
||||
})
|
||||
.then(setStats);
|
||||
});
|
||||
setStats(stats);
|
||||
setLoading(false);
|
||||
});
|
||||
return (
|
||||
<Grid class={s.Content} placeItems="start center">
|
||||
<Show when={stats()} fallback={<Loading type="three-dot" />}>
|
||||
<Show when={stats() && !loading()} fallback={<Loading type="three-dot" />}>
|
||||
<SimpleTabs
|
||||
localStorageKey="historical-stats-view-v3"
|
||||
defaultSelected="basic"
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
import { useParams } from "@solidjs/router";
|
||||
import { ParentComponent, createContext, useContext, createSignal, createResource } from "solid-js";
|
||||
import { client } from "../..";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
import { SystemInformation, Timelength } from "../../types";
|
||||
import { useLocalStorage } from "../../util/hooks";
|
||||
|
||||
export enum StatsView {
|
||||
Current = "current",
|
||||
Historical = "historical",
|
||||
Info = "info"
|
||||
}
|
||||
|
||||
const value = () => {
|
||||
const params = useParams();
|
||||
const [view, setView] = useLocalStorage("current", "stats-view-v1");
|
||||
const [view, setView] = useLocalStorage(StatsView.Current, "stats-view-v2");
|
||||
const [timelength, setTimelength] = useLocalStorage(
|
||||
Timelength.OneMinute,
|
||||
"stats-timelength-v3"
|
||||
@@ -16,12 +23,7 @@ const value = () => {
|
||||
`${params.id}-stats-poll-v3`
|
||||
);
|
||||
const [page, setPage] = createSignal(0);
|
||||
// const [wsOpen, setWsOpen] = createSignal(false);
|
||||
const [sysInfo] = createResource<SystemInformation>(() =>
|
||||
client.get_server_system_info(params.id)
|
||||
);
|
||||
return {
|
||||
sysInfo,
|
||||
view,
|
||||
setView,
|
||||
timelength,
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import { A, useParams } from "@solidjs/router";
|
||||
import {
|
||||
Component,
|
||||
Match,
|
||||
Show,
|
||||
Switch,
|
||||
} from "solid-js";
|
||||
import { MAX_PAGE_WIDTH } from "../..";
|
||||
import { Component, createResource, For, Match, Show, Switch } from "solid-js";
|
||||
import { client } from "../..";
|
||||
import { useAppState } from "../../state/StateProvider";
|
||||
import { ServerStatus, Timelength } from "../../types";
|
||||
import { readableStorageAmount } from "../../util/helpers";
|
||||
import Icon from "../shared/Icon";
|
||||
import Flex from "../shared/layout/Flex";
|
||||
import Grid from "../shared/layout/Grid";
|
||||
import Selector from "../shared/menu/Selector";
|
||||
import CurrentStats from "./CurrentStats";
|
||||
import HistoricalStats from "./HistoricalStats";
|
||||
import { StatsProvider, useStatsState } from "./Provider";
|
||||
import { StatsProvider, useStatsState, StatsView } from "./Provider";
|
||||
|
||||
const TIMELENGTHS = [
|
||||
Timelength.FifteenSeconds,
|
||||
@@ -38,115 +34,182 @@ const Stats = () => {
|
||||
const StatsComp: Component<{}> = () => {
|
||||
const { view } = useStatsState();
|
||||
return (
|
||||
<Grid
|
||||
style={{
|
||||
width: "100%",
|
||||
"box-sizing": "border-box",
|
||||
}}
|
||||
>
|
||||
<Flex justifyContent="space-between" style={{ width: "100%" }}>
|
||||
<Header />
|
||||
<SysInfo />
|
||||
</Flex>
|
||||
<Show when={view() === "historical"}>
|
||||
<Grid class="full-width">
|
||||
<Header />
|
||||
<Show when={view() === StatsView.Historical}>
|
||||
<Flex alignItems="center" style={{ "place-self": "center" }}>
|
||||
<PageManager />
|
||||
</Flex>
|
||||
</Show>
|
||||
<Switch>
|
||||
<Match when={view() === "current"}>
|
||||
<Match when={view() === StatsView.Current}>
|
||||
<CurrentStats />
|
||||
</Match>
|
||||
<Match when={view() === "historical"}>
|
||||
<Match when={view() === StatsView.Historical}>
|
||||
<HistoricalStats />
|
||||
</Match>
|
||||
<Match when={view() === StatsView.Info}>
|
||||
<SysInfo />
|
||||
</Match>
|
||||
</Switch>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export const Header: Component<{}> = (p) => {
|
||||
const { servers } = useAppState();
|
||||
const { servers, serverInfo } = useAppState();
|
||||
const params = useParams();
|
||||
const server = () => servers.get(params.id);
|
||||
const { view, setView, timelength, setTimelength, setPage, pollRate, setPollRate } = useStatsState();
|
||||
const {
|
||||
view,
|
||||
setView,
|
||||
timelength,
|
||||
setTimelength,
|
||||
setPage,
|
||||
pollRate,
|
||||
setPollRate,
|
||||
} = useStatsState();
|
||||
const sysInfo = () => serverInfo.get(params.id);
|
||||
return (
|
||||
<Flex alignItems="center" style={{ height: "fit-content" }}>
|
||||
<h1>{server()?.server.name}</h1>
|
||||
<A
|
||||
href={`/server/${params.id}`}
|
||||
class={
|
||||
server()?.server.enabled
|
||||
? server()?.status === ServerStatus.Ok
|
||||
? "green"
|
||||
: "red"
|
||||
: "blue"
|
||||
}
|
||||
style={{
|
||||
"border-radius": ".35rem",
|
||||
transition: "background-color 125ms ease-in-out",
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{server()?.status.replaceAll("_", " ").toUpperCase()}
|
||||
</A>
|
||||
<Grid gap="0" gridTemplateColumns="repeat(2, 1fr)">
|
||||
<button
|
||||
class={view() === "current" ? "selected" : "grey"}
|
||||
style={{ width: "100%" }}
|
||||
onClick={() => setView("current")}
|
||||
>
|
||||
current
|
||||
</button>
|
||||
<button
|
||||
class={view() === "historical" ? "selected" : "grey"}
|
||||
style={{ width: "100%" }}
|
||||
onClick={() => setView("historical")}
|
||||
>
|
||||
historical
|
||||
</button>
|
||||
</Grid>
|
||||
<Show when={view() === "historical"}>
|
||||
<Selector
|
||||
targetClass="grey"
|
||||
selected={timelength()}
|
||||
items={TIMELENGTHS}
|
||||
onSelect={(selected) => {
|
||||
setPage(0);
|
||||
setTimelength(selected as Timelength);
|
||||
<Flex alignItems="center" justifyContent="space-between">
|
||||
<Flex alignItems="center" style={{ height: "fit-content" }}>
|
||||
<h1>{server()?.server.name}</h1>
|
||||
<A
|
||||
href={`/server/${params.id}`}
|
||||
class={
|
||||
server()?.server.enabled
|
||||
? server()?.status === ServerStatus.Ok
|
||||
? "green"
|
||||
: "red"
|
||||
: "blue"
|
||||
}
|
||||
style={{
|
||||
"border-radius": ".35rem",
|
||||
transition: "background-color 125ms ease-in-out",
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
{server()?.status.replaceAll("_", " ").toUpperCase()}
|
||||
</A>
|
||||
<Selector
|
||||
targetClass="blue"
|
||||
selected={view()}
|
||||
items={Object.values(StatsView)}
|
||||
onSelect={(v) => setView(v as StatsView)}
|
||||
position="bottom right"
|
||||
/>
|
||||
</Show>
|
||||
<Show when={view() === "current"}>
|
||||
<Flex gap="0.5rem" alignItems="center">
|
||||
<div>poll:</div>
|
||||
<Show when={view() === "historical"}>
|
||||
<Selector
|
||||
targetClass="grey"
|
||||
selected={timelength()}
|
||||
items={TIMELENGTHS}
|
||||
itemMap={(t) => t.replaceAll("-", " ")}
|
||||
itemClass="full-width"
|
||||
onSelect={(selected) => {
|
||||
setPage(0);
|
||||
setTimelength(selected as Timelength);
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
</Show>
|
||||
<Show when={view() === "current"}>
|
||||
<Selector
|
||||
targetClass="grey"
|
||||
label="poll: "
|
||||
selected={pollRate()}
|
||||
items={[Timelength.OneSecond, Timelength.FiveSeconds]}
|
||||
onSelect={(selected) => {
|
||||
setPollRate(selected as Timelength);
|
||||
}}
|
||||
position="bottom right"
|
||||
/>
|
||||
</Flex>
|
||||
</Show>
|
||||
</Show>
|
||||
</Flex>
|
||||
<Flex>
|
||||
<div>{sysInfo()?.cpu_brand}</div>
|
||||
<div>
|
||||
{sysInfo()?.core_count} core
|
||||
{sysInfo()?.core_count && sysInfo()?.core_count! > 1 ? "s" : ""}
|
||||
</div>
|
||||
</Flex>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
const SysInfo = () => {
|
||||
const { sysInfo } = useStatsState();
|
||||
const { serverInfo } = useAppState();
|
||||
const params = useParams();
|
||||
const sysInfo = () => serverInfo.get(params.id);
|
||||
const [stats] = createResource(() =>
|
||||
client.get_server_stats(params.id, { disks: true })
|
||||
);
|
||||
const os_cards = () => {
|
||||
return [
|
||||
{
|
||||
label: "os",
|
||||
info: sysInfo()?.os,
|
||||
},
|
||||
{
|
||||
label: "kernel",
|
||||
info: sysInfo()?.kernel,
|
||||
},
|
||||
].filter((i) => i.info) as Array<{ label: string; info: string }>;
|
||||
};
|
||||
const cpu_cards = () => {
|
||||
return [
|
||||
{
|
||||
label: "cpu",
|
||||
info: sysInfo()?.cpu_brand,
|
||||
},
|
||||
{
|
||||
label: "core count",
|
||||
info: `${sysInfo()?.core_count} cores`,
|
||||
},
|
||||
].filter((i) => i.info) as Array<{ label: string; info: string }>;
|
||||
};
|
||||
const stats_cards = () => {
|
||||
return [
|
||||
{
|
||||
label: "mem",
|
||||
info:
|
||||
stats()?.mem_total_gb &&
|
||||
readableStorageAmount(stats()?.mem_total_gb!),
|
||||
},
|
||||
{
|
||||
label: "disk",
|
||||
info:
|
||||
stats()?.disk.total_gb &&
|
||||
readableStorageAmount(stats()?.disk.total_gb!),
|
||||
},
|
||||
].filter((i) => i.info) as Array<{ label: string; info: string }>;
|
||||
};
|
||||
return (
|
||||
<Flex
|
||||
alignItems="center"
|
||||
style={{ "place-self": "center end", width: "fit-content" }}
|
||||
>
|
||||
<div>{sysInfo()?.os}</div>
|
||||
{/* <div>{sysInfo()?.kernel}</div> */}
|
||||
<div>{sysInfo()?.cpu_brand}</div>
|
||||
<div>{sysInfo()?.core_count} cores</div>
|
||||
<Grid class="full-width" placeItems="center">
|
||||
<Show when={sysInfo()?.host_name}>
|
||||
<Grid class="card full-width" style={{ "max-width": "700px" }}>
|
||||
<InfoCard info={{ label: "hostname", info: sysInfo()?.host_name! }} />
|
||||
</Grid>
|
||||
</Show>
|
||||
<Grid class="card full-width" style={{ "max-width": "700px" }}>
|
||||
<For each={os_cards()}>{(i) => <InfoCard info={i} />}</For>
|
||||
</Grid>
|
||||
<Grid class="card full-width" style={{ "max-width": "700px" }}>
|
||||
<For each={cpu_cards()}>{(i) => <InfoCard info={i} />}</For>
|
||||
</Grid>
|
||||
<Grid class="card full-width" style={{ "max-width": "700px" }}>
|
||||
<For each={stats_cards()}>{(i) => <InfoCard info={i} />}</For>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
const InfoCard: Component<{ info: { label: string; info: string } }> = (p) => {
|
||||
return (
|
||||
<Flex class="full-width" justifyContent="space-between">
|
||||
<h2>{p.info.label}</h2>
|
||||
<div>{p.info.info}</div>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -58,7 +58,8 @@ export const Search: Component<{}> = (p) => {
|
||||
>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
class={s.SearchInput}
|
||||
class="lightgrey"
|
||||
style={{ width: "30rem" }}
|
||||
placeholder="search"
|
||||
value={search.value()}
|
||||
onEdit={input.onEdit}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { UserProvider } from "./state/UserProvider";
|
||||
import { Client } from "./util/client";
|
||||
import { Router } from "@solidjs/router";
|
||||
import { AppStateProvider } from "./state/StateProvider";
|
||||
import { Operation } from "./types";
|
||||
|
||||
export const TOPBAR_HEIGHT = 50;
|
||||
export const MAX_PAGE_WIDTH = 1200;
|
||||
@@ -29,6 +30,10 @@ const token =
|
||||
|
||||
export const client = new Client(MONITOR_BASE_URL, token);
|
||||
|
||||
export const OPERATIONS = Object.values(Operation)
|
||||
.filter((e) => e !== "none" && !e.includes("user"))
|
||||
.map((e) => e.replaceAll("_", " "));
|
||||
|
||||
export const { Notifications, pushNotification } = makeNotifications();
|
||||
|
||||
client.initialize().then(() => {
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from "./hooks";
|
||||
import connectToWs from "./ws";
|
||||
import { useUser } from "./UserProvider";
|
||||
import { AwsBuilderConfig, PermissionLevel } from "../types";
|
||||
import { AwsBuilderConfig, PermissionLevel, UpdateTarget } from "../types";
|
||||
import { client } from "..";
|
||||
|
||||
export type State = {
|
||||
@@ -42,6 +42,7 @@ export type State = {
|
||||
aws_builder_config: Resource<AwsBuilderConfig>;
|
||||
docker_organizations: Resource<string[]>;
|
||||
github_webhook_base_url: Resource<string>;
|
||||
name_from_update_target: (target: UpdateTarget) => string;
|
||||
};
|
||||
|
||||
const context = createContext<
|
||||
@@ -148,6 +149,17 @@ export const AppStateProvider: ParentComponent = (p) => {
|
||||
aws_builder_config,
|
||||
docker_organizations,
|
||||
github_webhook_base_url,
|
||||
name_from_update_target: (target) => {
|
||||
if (target.type === "Deployment" && deployments) {
|
||||
return deployments.get(target.id!)?.deployment.name || "deleted";
|
||||
} else if (target.type === "Server" && servers) {
|
||||
return servers.get(target.id)?.server.name || "deleted";
|
||||
} else if (target.type === "Build" && builds) {
|
||||
return builds.get(target.id)?.name || "deleted";
|
||||
} else {
|
||||
return "admin";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// createEffect(() => {
|
||||
|
||||
@@ -288,7 +288,7 @@ export function useUpdates(target?: UpdateTarget, show_builds?: boolean) {
|
||||
operations
|
||||
);
|
||||
updates.addManyToEnd(newUpdates);
|
||||
if (newUpdates.length !== 10) {
|
||||
if (newUpdates.length !== 20) {
|
||||
setNoMore(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +318,22 @@ svg {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.full-size {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// .hoverable {
|
||||
// transition: all 250ms ease-in-out;
|
||||
// }
|
||||
|
||||
@@ -56,6 +56,8 @@ export interface DockerBuildArgs {
|
||||
build_path: string;
|
||||
dockerfile_path?: string;
|
||||
build_args?: EnvironmentVar[];
|
||||
extra_args?: string[];
|
||||
use_buildx?: boolean;
|
||||
}
|
||||
|
||||
export interface BuildVersionsReponse {
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import {
|
||||
Build,
|
||||
Deployment,
|
||||
DeploymentWithContainerState,
|
||||
DockerContainerState,
|
||||
EnvironmentVar,
|
||||
Server,
|
||||
ServerStatus,
|
||||
ServerWithStatus,
|
||||
Timelength,
|
||||
UpdateTarget,
|
||||
User,
|
||||
Version,
|
||||
} from "../types";
|
||||
@@ -238,10 +244,10 @@ export function readableVersion(version: Version) {
|
||||
|
||||
export function readableUserType(user: User) {
|
||||
if (user.github_id) {
|
||||
return "github"
|
||||
return "github";
|
||||
} else if (user.google_id) {
|
||||
return "google"
|
||||
return "google";
|
||||
} else {
|
||||
return "local"
|
||||
return "local";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "db_client"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "monitor_helpers"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
authors = ["MoghTech"]
|
||||
description = "helpers used as dependency for mogh tech monitor"
|
||||
|
||||
@@ -1,113 +1,10 @@
|
||||
use std::{borrow::Borrow, fs::File, io::Read, net::SocketAddr, str::FromStr};
|
||||
use std::{borrow::Borrow, net::SocketAddr, str::FromStr};
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
use anyhow::anyhow;
|
||||
use axum::http::StatusCode;
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde_json::{Map, Value};
|
||||
use types::Log;
|
||||
|
||||
pub fn parse_config_files<'a, T: DeserializeOwned>(
|
||||
paths: impl IntoIterator<Item = impl Borrow<String>>,
|
||||
merge_nested: bool,
|
||||
extend_array: bool,
|
||||
) -> anyhow::Result<T> {
|
||||
let mut target = Map::new();
|
||||
for path in paths {
|
||||
target = merge_objects(
|
||||
target,
|
||||
parse_config_file(path.borrow())?,
|
||||
merge_nested,
|
||||
extend_array,
|
||||
)?;
|
||||
}
|
||||
serde_json::from_str(&serde_json::to_string(&target)?)
|
||||
.context("failed to parse final config into expected type")
|
||||
}
|
||||
|
||||
pub fn parse_config_file<T: DeserializeOwned>(path: &str) -> anyhow::Result<T> {
|
||||
let mut file = File::open(&path).expect(&format!("failed to find config at {path}"));
|
||||
let config = if path.ends_with("toml") {
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)
|
||||
.context(format!("failed to read toml at {path}"))?;
|
||||
toml::from_str(&contents).context(format!("failed to parse toml at {path}"))?
|
||||
} else if path.ends_with("json") {
|
||||
serde_json::from_reader(file).context(format!("failed to parse json at {path}"))?
|
||||
} else {
|
||||
panic!("unsupported config file type: {}", path)
|
||||
};
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
/// object is serde_json::Map<String, serde_json::Value>
|
||||
/// source will overide target
|
||||
/// will recurse when field is object if merge_object = true, otherwise object will be replaced
|
||||
/// will extend when field is array if extend_array = true, otherwise array will be replaced
|
||||
/// will return error when types on source and target fields do not match
|
||||
fn merge_objects(
|
||||
mut target: Map<String, Value>,
|
||||
source: Map<String, Value>,
|
||||
merge_nested: bool,
|
||||
extend_array: bool,
|
||||
) -> anyhow::Result<Map<String, Value>> {
|
||||
for (key, value) in source {
|
||||
let curr = target.remove(&key);
|
||||
if curr.is_none() {
|
||||
target.insert(key, value);
|
||||
continue;
|
||||
}
|
||||
let curr = curr.unwrap();
|
||||
match curr {
|
||||
Value::Object(target_obj) => {
|
||||
if !merge_nested {
|
||||
target.insert(key, value);
|
||||
continue;
|
||||
}
|
||||
match value {
|
||||
Value::Object(source_obj) => {
|
||||
target.insert(
|
||||
key,
|
||||
Value::Object(merge_objects(
|
||||
target_obj,
|
||||
source_obj,
|
||||
merge_nested,
|
||||
extend_array,
|
||||
)?),
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!(
|
||||
"types on field {key} do not match. got {value:?}, expected object"
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
Value::Array(mut target_arr) => {
|
||||
if !extend_array {
|
||||
target.insert(key, value);
|
||||
continue;
|
||||
}
|
||||
match value {
|
||||
Value::Array(source_arr) => {
|
||||
target_arr.extend(source_arr);
|
||||
target.insert(key, Value::Array(target_arr));
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!(
|
||||
"types on field {key} do not match. got {value:?}, expected array"
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
target.insert(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(target)
|
||||
}
|
||||
|
||||
pub fn parse_comma_seperated_list<T: FromStr>(
|
||||
comma_sep_list: impl Borrow<str>,
|
||||
) -> anyhow::Result<Vec<T>> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "monitor_client"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
authors = ["MoghTech"]
|
||||
description = "a client to interact with the monitor system"
|
||||
@@ -9,8 +9,7 @@ license = "GPL-3.0-or-later"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
monitor_types = "0.2.10"
|
||||
# monitor_types = { path = "../types" }
|
||||
monitor_types = "0.2.14"
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
tokio-tungstenite = { version = "0.18", features=["native-tls"] }
|
||||
tokio = { version = "1.25", features = ["full"] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "periphery_client"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "monitor_types"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
authors = ["MoghTech"]
|
||||
description = "types for the mogh tech monitor"
|
||||
|
||||
@@ -155,6 +155,12 @@ pub struct DockerBuildArgs {
|
||||
#[serde(default)]
|
||||
#[builder(default)]
|
||||
pub build_args: Vec<EnvironmentVar>,
|
||||
#[serde(default)]
|
||||
#[builder(default)]
|
||||
pub extra_args: Vec<String>,
|
||||
#[serde(default)]
|
||||
#[builder(default)]
|
||||
pub use_buildx: bool,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "monitor_periphery"
|
||||
version = "0.2.10"
|
||||
version = "0.2.14"
|
||||
edition = "2021"
|
||||
authors = ["MoghTech"]
|
||||
description = "monitor periphery binary"
|
||||
@@ -31,5 +31,6 @@ envy = "0.4"
|
||||
sysinfo = "0.28"
|
||||
toml = "0.7"
|
||||
daemonize = "0.5.0"
|
||||
clap = { version = "4.1", features = ["derive"] }
|
||||
clap = { version = "4.2", features = ["derive"] }
|
||||
svi = "0.1.3"
|
||||
merge_config_files = "0.1.3"
|
||||
|
||||
@@ -3,7 +3,8 @@ use std::sync::Arc;
|
||||
use axum::Extension;
|
||||
use clap::Parser;
|
||||
use dotenv::dotenv;
|
||||
use helpers::{parse_comma_seperated_list, parse_config_files};
|
||||
use helpers::parse_comma_seperated_list;
|
||||
use merge_config_files::parse_config_paths;
|
||||
use serde::Deserialize;
|
||||
use types::PeripheryConfig;
|
||||
|
||||
@@ -25,14 +26,18 @@ pub struct Args {
|
||||
#[arg(long, default_value = "~/.monitor/periphery.log.err")]
|
||||
pub stderr: String,
|
||||
|
||||
/// Sets the path of a config file to use. can use multiple times
|
||||
/// Sets the path of a config file or directory to use. can use multiple times
|
||||
#[arg(short, long)]
|
||||
pub config_path: Option<Vec<String>>,
|
||||
|
||||
/// Sets the keywords to match directory periphery config file names on. can use multiple times. default "periphery" and "config"
|
||||
#[arg(long)]
|
||||
pub config_keyword: Option<Vec<String>>,
|
||||
|
||||
#[arg(short, long)]
|
||||
pub merge_nested_config: bool,
|
||||
|
||||
#[arg(short, long)]
|
||||
#[arg(long)]
|
||||
pub home_dir: Option<String>,
|
||||
|
||||
#[arg(short, long)]
|
||||
@@ -43,6 +48,8 @@ pub struct Args {
|
||||
struct Env {
|
||||
#[serde(default = "default_config_path")]
|
||||
config_paths: String,
|
||||
#[serde(default)]
|
||||
config_keywords: String,
|
||||
}
|
||||
|
||||
pub fn load() -> (Args, u16, PeripheryConfigExtension, HomeDirExtension) {
|
||||
@@ -63,9 +70,18 @@ pub fn load() -> (Args, u16, PeripheryConfigExtension, HomeDirExtension) {
|
||||
)
|
||||
.into_iter()
|
||||
.map(|p| p.replace("~", &home_dir))
|
||||
.collect();
|
||||
let config = parse_config_files::<PeripheryConfig>(
|
||||
&config_paths,
|
||||
.collect::<Vec<_>>();
|
||||
let env_match_keywords = parse_comma_seperated_list(env.config_keywords)
|
||||
.expect("failed to parse environemt CONFIG_KEYWORDS into comma seperated list");
|
||||
let match_keywords = args
|
||||
.config_keyword
|
||||
.as_ref()
|
||||
.unwrap_or(&env_match_keywords)
|
||||
.into_iter()
|
||||
.map(|kw| kw.as_str());
|
||||
let config = parse_config_paths::<PeripheryConfig>(
|
||||
config_paths.clone(),
|
||||
match_keywords,
|
||||
args.merge_nested_config,
|
||||
args.merge_nested_config,
|
||||
)
|
||||
@@ -117,7 +133,7 @@ fn default_config_path() -> String {
|
||||
fn get_home_dir(home_dir_arg: &Option<String>) -> String {
|
||||
match home_dir_arg {
|
||||
Some(home_dir) => home_dir.to_string(),
|
||||
None => std::env::var("$HOME")
|
||||
None => std::env::var("HOME")
|
||||
.expect("did not find $HOME env var, should pass home dir with arg --home-dir"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use types::{Build, DockerBuildArgs, EnvironmentVar, Log, Version};
|
||||
|
||||
use crate::helpers::run_monitor_command;
|
||||
|
||||
use super::docker_login;
|
||||
use super::{docker_login, parse_extra_args};
|
||||
|
||||
pub async fn prune_images() -> Log {
|
||||
let command = format!("docker image prune -a -f");
|
||||
@@ -32,6 +32,8 @@ pub async fn build(
|
||||
build_path,
|
||||
dockerfile_path,
|
||||
build_args,
|
||||
extra_args,
|
||||
use_buildx,
|
||||
} = docker_build_args
|
||||
.as_ref()
|
||||
.ok_or(anyhow!("build missing docker build args"))?;
|
||||
@@ -46,6 +48,8 @@ pub async fn build(
|
||||
None => "Dockerfile".to_owned(),
|
||||
};
|
||||
let build_args = parse_build_args(build_args);
|
||||
let extra_args = parse_extra_args(extra_args);
|
||||
let buildx = if *use_buildx { " buildx" } else { "" };
|
||||
let image_name = get_image_name(&name, docker_account, docker_organization);
|
||||
let image_tags = image_tags(&image_name, &version);
|
||||
let docker_push = if using_account {
|
||||
@@ -54,7 +58,7 @@ pub async fn build(
|
||||
String::new()
|
||||
};
|
||||
let command = format!(
|
||||
"cd {} && docker build {build_args}{image_tags} -f {dockerfile_path} .{docker_push}",
|
||||
"cd {} && docker{buildx} build{build_args}{extra_args}{image_tags} -f {dockerfile_path} .{docker_push}",
|
||||
build_dir.display()
|
||||
);
|
||||
if *skip_secret_interp {
|
||||
@@ -97,7 +101,7 @@ fn get_latest_image_name(image_name: &str) -> String {
|
||||
|
||||
fn image_tags(image_name: &str, version: &Version) -> String {
|
||||
format!(
|
||||
"-t {} -t {}",
|
||||
" -t {} -t {}",
|
||||
get_version_image_name(image_name, version),
|
||||
get_latest_image_name(image_name)
|
||||
)
|
||||
|
||||
@@ -7,7 +7,7 @@ use types::{
|
||||
Conversion, Deployment, DockerContainerStats, DockerRunArgs, EnvironmentVar, Log, RestartMode,
|
||||
};
|
||||
|
||||
use crate::helpers::run_monitor_command;
|
||||
use crate::helpers::{docker::parse_extra_args, run_monitor_command};
|
||||
|
||||
use super::docker_login;
|
||||
|
||||
@@ -197,12 +197,3 @@ fn parse_post_image(post_image: &Option<String>) -> String {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_extra_args(extra_args: &Vec<String>) -> String {
|
||||
let args = extra_args.join(" ");
|
||||
if args.len() > 0 {
|
||||
format!(" {args}")
|
||||
} else {
|
||||
args
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,3 +38,12 @@ pub async fn docker_login(
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_extra_args(extra_args: &Vec<String>) -> String {
|
||||
let args = extra_args.join(" ");
|
||||
if args.len() > 0 {
|
||||
format!(" {args}")
|
||||
} else {
|
||||
args
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,8 +108,7 @@ pub async fn test_build(monitor: &MonitorClient) -> anyhow::Result<Update> {
|
||||
});
|
||||
build.docker_build_args = Some(DockerBuildArgs {
|
||||
build_path: "periphery".to_string(),
|
||||
dockerfile_path: None,
|
||||
build_args: Vec::new(),
|
||||
..Default::default()
|
||||
});
|
||||
let build = monitor.update_build(build).await?;
|
||||
println!("updated build.");
|
||||
|
||||
Reference in New Issue
Block a user