diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index d4f7835..0efedc9 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -16,6 +16,8 @@
"seccomp=unconfined"
],
+ "postCreateCommand": "cargo install cross",
+
"mounts": [
"source=/etc/timezone,target=/etc/timezone,type=bind,readonly"
],
diff --git a/.github/release-body.md b/.github/release-body.md
index be03e66..e92a330 100644
--- a/.github/release-body.md
+++ b/.github/release-body.md
@@ -1,16 +1,20 @@
-### 2023-01-03
+### 2023-01-21
### Chores
-+ dependencies updated, [9b09146aadae5727a5fee4de5fe0c1d70c581c22]
++ dependencies updated, [8cd199db49186fad6ce432bb277e3a10f0a08d34], [d880b829c123dbe57deccadef97810e45c083737], [66d57c99558ca14d9593d6dbfd5b0e8e5d59055d], [33f9374908942f4a3b90be227fad94ca353cf351], [007d5d83d7f1b93e1e78777a4417b2740db706bd]
++ create_release.sh typos, [9a27d46a044452080144ee1367dc95886b10abf8]
++ dev container post create install cross, [2d253f034182741d434e4bac12317f24221d0d4a]
### Features
-+ `install.sh` script added, for automated platform selection, download, and installation, [7a42eba6b0968314af40ff87bcc42d288f6860bc], [e0703b76a1a28cfe266f130a7f7dec92f1b5ad58]
-
-### Fixes
-+ If a sort order is set, sort containers on every `update_stats()` execution, [cfdea77594e48c8c20a4d6e6c7ea31c9181361a1]
+**all potentially considered breaking changes**
++ store Logs in own struct, use a hashset to track timestamps, hopefully closes #11, [657ea2d751a71f05b17547b47c492d5676817336]
++ Spawn docker commands into own thread, can now execute multiple docker commands at the same time, [9ec43e124a62a80f4e78acba85fc3af5980ce260]
++ align memory columns correctly, minimum byte display value now `0.00 kB`, rather than `0 B`, closes #20, [bd7dfcd2c512a527d66a1388f90006988a487186], [51c580010a24de2427373795803936d498dc8cee]
### Refactors
-+ input sort executed in app_data struct `sort_by_header()`, [3cdc5fae02097628799209f371ae9292e513e76c]
++ main.rs tidy up, [97b89349dc2de275ca514a1e6420255a63d775e8]
++ derive Default for GuiState, [9dcd0509efeb464f58fb53d813bd78de2447949d]
++ param reduction, AtomicBool to Relaxed, [0350293de3c00c6e5e5d787b7596bb3413d1cda1]
see CHANGELOG.md for more details
diff --git a/.github/screenshot_01.png b/.github/screenshot_01.png
index edcb52a..f45fffc 100644
Binary files a/.github/screenshot_01.png and b/.github/screenshot_01.png differ
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5219847..f7db59b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
+# v0.2.0
+### 2023-01-21
+
+### Chores
++ dependencies updated, [8cd199db](https://github.com/mrjackwills/oxker/commit/8cd199db49186fad6ce432bb277e3a10f0a08d34), [d880b829](https://github.com/mrjackwills/oxker/commit/d880b829c123dbe57deccadef97810e45c083737), [66d57c99](https://github.com/mrjackwills/oxker/commit/66d57c99558ca14d9593d6dbfd5b0e8e5d59055d), [33f93749](https://github.com/mrjackwills/oxker/commit/33f9374908942f4a3b90be227fad94ca353cf351), [007d5d83](https://github.com/mrjackwills/oxker/commit/007d5d83d7f1b93e1e78777a4417b2740db706bd)
++ create_release.sh typos, [9a27d46a](https://github.com/mrjackwills/oxker/commit/9a27d46a044452080144ee1367dc95886b10abf8)
++ dev container post create install cross, [2d253f03](https://github.com/mrjackwills/oxker/commit/2d253f034182741d434e4bac12317f24221d0d4a)
+
+### Features
+**all potentially considered breaking changes**
++ store Logs in own struct, use a hashset to track timestamps, hopefully closes [#11](https://github.com/mrjackwills/oxker/issues/11), [657ea2d7](https://github.com/mrjackwills/oxker/commit/657ea2d751a71f05b17547b47c492d5676817336)
++ Spawn docker commands into own thread, can now execute multiple docker commands at the same time, [9ec43e12](https://github.com/mrjackwills/oxker/commit/9ec43e124a62a80f4e78acba85fc3af5980ce260)
++ align memory columns correctly, minimum byte display value now `0.00 kB`, rather than `0 B`, closes [#20](https://github.com/mrjackwills/oxker/issues/20), [bd7dfcd2](https://github.com/mrjackwills/oxker/commit/bd7dfcd2c512a527d66a1388f90006988a487186), [51c58001](https://github.com/mrjackwills/oxker/commit/51c580010a24de2427373795803936d498dc8cee)
+
+### Refactors
++ main.rs tidy up, [97b89349](https://github.com/mrjackwills/oxker/commit/97b89349dc2de275ca514a1e6420255a63d775e8)
++ derive Default for GuiState, [9dcd0509](https://github.com/mrjackwills/oxker/commit/9dcd0509efeb464f58fb53d813bd78de2447949d)
++ param reduction, AtomicBool to Relaxed, [0350293d](https://github.com/mrjackwills/oxker/commit/0350293de3c00c6e5e5d787b7596bb3413d1cda1)
+
# v0.1.11
### 2023-01-03
diff --git a/Cargo.lock b/Cargo.lock
index 2776d80..0dcf962 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "anyhow"
version = "1.0.68"
@@ -20,6 +29,12 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+[[package]]
+name = "base64"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
+
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -28,11 +43,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bollard"
-version = "0.13.0"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d82e7850583ead5f8bbef247e2a3c37a19bd576e8420cd262a6711921827e1e5"
+checksum = "af254ed2da4936ef73309e9597180558821cb16ae9bba4cb24ce6b612d8d80ed"
dependencies = [
- "base64",
+ "base64 0.21.0",
"bollard-stubs",
"bytes",
"futures-core",
@@ -46,6 +61,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
+ "serde_repr",
"serde_urlencoded",
"thiserror",
"tokio",
@@ -56,14 +72,20 @@ dependencies = [
[[package]]
name = "bollard-stubs"
-version = "1.42.0-rc.3"
+version = "1.42.0-rc.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed59b5c00048f48d7af971b71f800fdf23e858844a6f9e4d32ca72e9399e7864"
+checksum = "602bda35f33aeb571cef387dcd4042c643a8bf689d8aaac2cc47ea24cb7bc7e0"
dependencies = [
"serde",
"serde_with",
]
+[[package]]
+name = "bumpalo"
+version = "3.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
+
[[package]]
name = "bytes"
version = "1.3.0"
@@ -95,10 +117,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
-name = "clap"
-version = "4.0.32"
+name = "chrono"
+version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
+checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
+dependencies = [
+ "iana-time-zone",
+ "num-integer",
+ "num-traits",
+ "serde",
+ "winapi",
+]
+
+[[package]]
+name = "clap"
+version = "4.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec7a4128863c188deefe750ac1d1dfe66c236909f845af04beed823638dc1b2"
dependencies = [
"bitflags",
"clap_derive",
@@ -113,9 +148,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.0.21"
+version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
+checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
dependencies = [
"heck",
"proc-macro-error",
@@ -126,13 +161,29 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.3.0"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
+checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
dependencies = [
"os_str_bytes",
]
+[[package]]
+name = "codespan-reporting"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+dependencies = [
+ "termcolor",
+ "unicode-width",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+
[[package]]
name = "crossterm"
version = "0.25.0"
@@ -159,36 +210,45 @@ dependencies = [
]
[[package]]
-name = "darling"
-version = "0.13.4"
+name = "cxx"
+version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
+checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e"
dependencies = [
- "darling_core",
- "darling_macro",
+ "cc",
+ "cxxbridge-flags",
+ "cxxbridge-macro",
+ "link-cplusplus",
]
[[package]]
-name = "darling_core"
-version = "0.13.4"
+name = "cxx-build"
+version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610"
+checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200"
dependencies = [
- "fnv",
- "ident_case",
+ "cc",
+ "codespan-reporting",
+ "once_cell",
"proc-macro2",
"quote",
- "strsim",
+ "scratch",
"syn",
]
[[package]]
-name = "darling_macro"
-version = "0.13.4"
+name = "cxxbridge-flags"
+version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
+checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea"
+
+[[package]]
+name = "cxxbridge-macro"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e"
dependencies = [
- "darling_core",
+ "proc-macro2",
"quote",
"syn",
]
@@ -410,10 +470,28 @@ dependencies = [
]
[[package]]
-name = "ident_case"
-version = "1.0.1"
+name = "iana-time-zone"
+version = "0.1.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "winapi",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+dependencies = [
+ "cxx",
+ "cxx-build",
+]
[[package]]
name = "idna"
@@ -433,13 +511,14 @@ checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
+ "serde",
]
[[package]]
name = "io-lifetimes"
-version = "1.0.3"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
+checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
dependencies = [
"libc",
"windows-sys",
@@ -463,6 +542,15 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -475,6 +563,15 @@ version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+[[package]]
+name = "link-cplusplus"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
+dependencies = [
+ "cc",
+]
+
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
@@ -528,6 +625,25 @@ dependencies = [
"winapi",
]
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
[[package]]
name = "num_cpus"
version = "1.15.0"
@@ -558,7 +674,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "oxker"
-version = "0.1.10"
+version = "0.1.11"
dependencies = [
"anyhow",
"bollard",
@@ -586,9 +702,9 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.5"
+version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba"
+checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf"
dependencies = [
"cfg-if",
"libc",
@@ -667,9 +783,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.49"
+version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
+checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
dependencies = [
"unicode-ident",
]
@@ -724,9 +840,9 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.36.6"
+version = "0.36.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
+checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03"
dependencies = [
"bitflags",
"errno",
@@ -748,6 +864,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+[[package]]
+name = "scratch"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
+
[[package]]
name = "serde"
version = "1.0.152"
@@ -779,6 +901,17 @@ dependencies = [
"serde",
]
+[[package]]
+name = "serde_repr"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
@@ -793,24 +926,17 @@ dependencies = [
[[package]]
name = "serde_with"
-version = "1.14.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff"
+checksum = "30d904179146de381af4c93d3af6ca4984b3152db687dacb9c3c35e86f39809c"
dependencies = [
+ "base64 0.13.1",
+ "chrono",
+ "hex",
+ "indexmap",
"serde",
- "serde_with_macros",
-]
-
-[[package]]
-name = "serde_with_macros"
-version = "1.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
-dependencies = [
- "darling",
- "proc-macro2",
- "quote",
- "syn",
+ "serde_json",
+ "time",
]
[[package]]
@@ -896,9 +1022,9 @@ dependencies = [
[[package]]
name = "termcolor"
-version = "1.1.3"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
@@ -932,6 +1058,33 @@ dependencies = [
"once_cell",
]
+[[package]]
+name = "time"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
+dependencies = [
+ "itoa",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+
+[[package]]
+name = "time-macros"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
+dependencies = [
+ "time-core",
+]
+
[[package]]
name = "tinyvec"
version = "1.6.0"
@@ -949,9 +1102,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tokio"
-version = "1.23.0"
+version = "1.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
+checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
dependencies = [
"autocfg",
"bytes",
@@ -1058,9 +1211,9 @@ dependencies = [
[[package]]
name = "try-lock"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "tui"
@@ -1086,9 +1239,9 @@ dependencies = [
[[package]]
name = "unicode-bidi"
-version = "0.3.8"
+version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
[[package]]
name = "unicode-ident"
@@ -1166,6 +1319,60 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
[[package]]
name = "winapi"
version = "0.3.9"
@@ -1214,42 +1421,42 @@ dependencies = [
[[package]]
name = "windows_aarch64_gnullvm"
-version = "0.42.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_msvc"
-version = "0.42.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_i686_gnu"
-version = "0.42.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_msvc"
-version = "0.42.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_x86_64_gnu"
-version = "0.42.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnullvm"
-version = "0.42.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_msvc"
-version = "0.42.0"
+version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
diff --git a/Cargo.toml b/Cargo.toml
index 5eb5908..f01d9ef 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "oxker"
-version = "0.1.11"
+version = "0.2.0"
edition = "2021"
authors = ["Jack Wills "]
description = "A simple tui to view & control docker containers"
@@ -13,13 +13,13 @@ categories = ["command-line-utilities"]
[dependencies]
anyhow = "1.0"
-bollard = "0.13"
+bollard = "0.14"
cansi = "2.2"
-clap={version="4.0", features = ["derive", "unicode", "color"] }
+clap={version="4.1", features = ["derive", "unicode", "color"] }
crossterm = "0.25"
futures-util = "0.3"
parking_lot = {version= "0.12"}
-tokio = {version = "1.23", features=["full"]}
+tokio = {version = "1.24", features=["full"]}
tracing = "0.1"
tracing-subscriber = "0.3"
tui = "0.19"
diff --git a/README.md b/README.md
index c73c654..52660c0 100644
--- a/README.md
+++ b/README.md
@@ -51,7 +51,7 @@ rm oxker_linux_x86_64.tar.gz oxker
or, for automatic platform selection, download, and installation (to `$HOME/.local/bin`)
-*One should verify all scripts before running in your shell*
+*One should always verify script content before running in a shell*
```bash
curl https://raw.githubusercontent.com/mrjackwills/oxker/main/install.sh | bash
diff --git a/create_release.sh b/create_release.sh
index 64e5193..f04c721 100755
--- a/create_release.sh
+++ b/create_release.sh
@@ -105,11 +105,11 @@ update_release_body_and_changelog () {
# Update changelog to add links to commits [hex:8](url_with_full_commit)
# "[aaaaaaaaaabbbbbbbbbbccccccccccddddddddd]" -> "[aaaaaaaa](https:/www.../commit/aaaaaaaaaabbbbbbbbbbccccccccccddddddddd)"
- sed -i -E "s=(\s)\[([0-9a-f]{8})([0-9a-f]{32})\]= [\2](${GIT_REPO_URL}/commit/\2\3)=g" ./CHANGELOG.md
+ sed -i -E "s=(\s)\[([0-9a-f]{8})([0-9a-f]{32})\]= [\2](${GIT_REPO_URL}/commit/\2\3)=g" CHANGELOG.md
- # Update changelog to add links to closed issues - comma included!
- # "closes #1" -> "closes [#1](https:/www.../issues/1),""
- sed -i -r -E "s=closes \#([0-9]+)=closes [#\1](${GIT_REPO_URL}/issues/\1)=g" ./CHANGELOG.md
+ # Update changelog to add links to closed issues
+ # "closes #1" -> "closes [#1](https:/www.../issues/1)""
+ sed -i -r -E "s=closes \#([0-9]+)=closes [#\1](${GIT_REPO_URL}/issues/\1)=g" CHANGELOG.md
}
# update version in cargo.toml, to match selected current version
diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs
index de271c8..efa2d81 100644
--- a/src/app_data/container_state.rs
+++ b/src/app_data/container_state.rs
@@ -1,4 +1,8 @@
-use std::{cmp::Ordering, collections::VecDeque, fmt};
+use std::{
+ cmp::Ordering,
+ collections::{HashSet, VecDeque},
+ fmt,
+};
use tui::{
style::Color,
@@ -343,8 +347,7 @@ impl fmt::Display for ByteStats {
let p = match as_f64 {
x if x >= ONE_GB => format!("{y:.2} GB", y = as_f64 / ONE_GB),
x if x >= ONE_MB => format!("{y:.2} MB", y = as_f64 / ONE_MB),
- x if x >= ONE_KB => format!("{y:.2} kB", y = as_f64 / ONE_KB),
- _ => format!("{} B", self.0),
+ _ => format!("{y:.2} kB", y = as_f64 / ONE_KB),
};
write!(f, "{p:>x$}", x = f.width().unwrap_or(1))
}
@@ -353,6 +356,87 @@ impl fmt::Display for ByteStats {
pub type MemTuple = (Vec<(f64, f64)>, ByteStats, State);
pub type CpuTuple = (Vec<(f64, f64)>, CpuStats, State);
+/// Used to make sure that each log entry, for each container, is unique,
+/// will only push a log entry into the logs vec if timetstamp of said log entry isn't in the hashset
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub struct LogsTz(String);
+
+/// The docker log, which should always contain a timestamp, is in the format `2023-01-14T19:13:30.783138328Z Lorem ipsum dolor sit amet`
+/// So just split at the inclusive index of the first space, needs to be inclusive, hence the use of format to at the space, so that we can remove the whole thing when the `-t` flag is set
+/// Need to make sure that this isn't an empty string?!
+impl From<&String> for LogsTz {
+ fn from(value: &String) -> Self {
+ Self(value.split_inclusive(' ').take(1).collect::())
+ }
+}
+
+impl fmt::Display for LogsTz {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}", self.0)
+ }
+}
+
+/// Store the logs alongside a HashSet, each log *should* generate a unique timestamp,
+/// so if we store the timestamp seperately in a HashSet, we can then check if we should insert a log line into the
+/// stateful list dependant on whethere the timestamp is in the HashSet or not
+#[derive(Debug, Clone)]
+pub struct Logs {
+ logs: StatefulList>,
+ tz: HashSet,
+}
+
+impl Default for Logs {
+ fn default() -> Self {
+ let mut logs = StatefulList::new(vec![]);
+ logs.end();
+ Self {
+ logs,
+ tz: HashSet::new(),
+ }
+ }
+}
+
+impl Logs {
+ /// Only allow a new log line to be inserted if the log timestamp isn't in the tz HashSet
+ pub fn insert(&mut self, line: ListItem<'static>, tz: LogsTz) {
+ if self.tz.insert(tz) {
+ self.logs.items.push(line);
+ };
+ }
+
+ pub fn to_vec(&self) -> Vec> {
+ self.logs.items.clone()
+ }
+
+ /// The rest of the methods are basically forwarding from the underlying StatefulList
+ pub fn get_state_title(&self) -> String {
+ self.logs.get_state_title()
+ }
+
+ pub fn next(&mut self) {
+ self.logs.next();
+ }
+
+ pub fn previous(&mut self) {
+ self.logs.previous();
+ }
+
+ pub fn end(&mut self) {
+ self.logs.end();
+ }
+ pub fn start(&mut self) {
+ self.logs.start();
+ }
+
+ pub fn len(&self) -> usize {
+ self.logs.items.len()
+ }
+
+ pub fn state(&mut self) -> &mut ListState {
+ &mut self.logs.state
+ }
+}
+
/// Info for each container
#[derive(Debug, Clone)]
pub struct ContainerItem {
@@ -362,7 +446,7 @@ pub struct ContainerItem {
pub id: ContainerId,
pub image: String,
pub last_updated: u64,
- pub logs: StatefulList>,
+ pub logs: Logs,
pub mem_limit: ByteStats,
pub mem_stats: VecDeque,
pub name: String,
@@ -386,8 +470,6 @@ impl ContainerItem {
) -> Self {
let mut docker_controls = StatefulList::new(DockerControls::gen_vec(state));
docker_controls.start();
- let mut logs = StatefulList::new(vec![]);
- logs.end();
Self {
created,
cpu_stats: VecDeque::with_capacity(60),
@@ -396,7 +478,7 @@ impl ContainerItem {
image,
is_oxker,
last_updated: 0,
- logs,
+ logs: Logs::default(),
mem_limit: ByteStats::default(),
mem_stats: VecDeque::with_capacity(60),
name,
@@ -463,15 +545,15 @@ impl ContainerItem {
/// Container information panel headings + widths, for nice pretty formatting
#[derive(Debug, Clone, Copy)]
pub struct Columns {
- pub state: (Header, usize),
- pub status: (Header, usize),
- pub cpu: (Header, usize),
- pub mem: (Header, usize),
- pub id: (Header, usize),
- pub name: (Header, usize),
- pub image: (Header, usize),
- pub net_rx: (Header, usize),
- pub net_tx: (Header, usize),
+ pub state: (Header, u8),
+ pub status: (Header, u8),
+ pub cpu: (Header, u8),
+ pub mem: (Header, u8, u8),
+ pub id: (Header, u8),
+ pub name: (Header, u8),
+ pub image: (Header, u8),
+ pub net_rx: (Header, u8),
+ pub net_tx: (Header, u8),
}
impl Columns {
@@ -480,14 +562,13 @@ impl Columns {
Self {
state: (Header::State, 11),
status: (Header::Status, 16),
- // 7 to allow for "100.00%"
cpu: (Header::Cpu, 7),
- mem: (Header::Memory, 12),
+ mem: (Header::Memory, 7, 7),
id: (Header::Id, 8),
name: (Header::Name, 4),
image: (Header::Image, 5),
- net_rx: (Header::Rx, 5),
- net_tx: (Header::Tx, 5),
+ net_rx: (Header::Rx, 7),
+ net_tx: (Header::Tx, 7),
}
}
}
diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs
index 8b92466..fc106f4 100644
--- a/src/app_data/mod.rs
+++ b/src/app_data/mod.rs
@@ -12,7 +12,6 @@ pub use container_state::*;
#[derive(Debug, Clone)]
pub struct AppData {
error: Option,
- logs_parsed: bool,
sorted_by: Option<(Header, SortedOrder)>,
pub args: CliArgs,
pub containers: StatefulList,
@@ -62,7 +61,6 @@ impl AppData {
args,
containers: StatefulList::new(vec![]),
error: None,
- logs_parsed: false,
sorted_by: None,
}
}
@@ -193,7 +191,7 @@ impl AppData {
/// Check if the selected container is a dockerised version of oxker
/// So that can disallow commands to be send
- /// Is a poor way of implementing this
+ /// Is a shabby way of implementing this
pub fn selected_container_is_oxker(&self) -> bool {
if let Some(index) = self.containers.state.selected() {
if let Some(x) = self.containers.items.get(index) {
@@ -352,7 +350,7 @@ impl AppData {
.iter()
.filter(|i| !i.cpu_stats.is_empty())
.count();
- self.logs_parsed && count_is_running == number_with_cpu_status
+ count_is_running == number_with_cpu_status
}
/// Just get the total number of containers
@@ -364,7 +362,7 @@ impl AppData {
/// So can display nicely and evenly
pub fn get_width(&self) -> Columns {
let mut output = Columns::new();
- let count = |x: &String| x.chars().count();
+ let count = |x: &String| u8::try_from(x.chars().count()).unwrap_or(12);
// Should probably find a refactor here somewhere
for container in &self.containers.items {
@@ -375,11 +373,6 @@ impl AppData {
.unwrap_or(&CpuStats::default())
.to_string(),
);
- let mem_count = count(&format!(
- "{} / {}",
- container.mem_stats.back().unwrap_or(&ByteStats::default()),
- container.mem_limit
- ));
let rx_count = count(&container.rx.to_string());
let tx_count = count(&container.tx.to_string());
@@ -387,6 +380,14 @@ impl AppData {
let name_count = count(&container.name);
let state_count = count(&container.state.to_string());
let status_count = count(&container.status);
+ let mem_current_count = count(
+ &container
+ .mem_stats
+ .back()
+ .unwrap_or(&ByteStats::default())
+ .to_string(),
+ );
+ let mem_limit_count = count(&container.mem_limit.to_string());
if cpu_count > output.cpu.1 {
output.cpu.1 = cpu_count;
@@ -394,8 +395,11 @@ impl AppData {
if image_count > output.image.1 {
output.image.1 = image_count;
};
- if mem_count > output.mem.1 {
- output.mem.1 = mem_count;
+ if mem_current_count > output.mem.1 {
+ output.mem.1 = mem_current_count;
+ };
+ if mem_limit_count > output.mem.2 {
+ output.mem.2 = mem_limit_count;
};
if name_count > output.name.1 {
output.name.1 = name_count;
@@ -548,8 +552,8 @@ impl AppData {
if item.image != image {
item.image = image;
};
- // else container not known, so make new ContainerItem and push into containers Vec
} else {
+ // container not known, so make new ContainerItem and push into containers Vec
let container =
ContainerItem::new(created, id, image, is_oxker, name, state, status);
self.containers.items.push(container);
@@ -559,34 +563,39 @@ impl AppData {
}
/// update logs of a given container, based on id
- pub fn update_log_by_id(&mut self, output: &[String], id: &ContainerId) {
- let tz = Self::get_systemtime();
+ pub fn update_log_by_id(&mut self, output: Vec, id: &ContainerId) {
let color = self.args.color;
let raw = self.args.raw;
- if let Some(container) = self.get_container_by_id(id) {
- container.last_updated = tz;
- let current_len = container.logs.items.len();
+ let timestamp = self.args.timestamp;
- for i in output {
+ if let Some(container) = self.get_container_by_id(id) {
+ container.last_updated = Self::get_systemtime();
+ let current_len = container.logs.len();
+
+ for mut i in output {
+ let tz = LogsTz::from(&i);
+ // Strip the timestamp if `-t` flag set
+ if !timestamp {
+ i = i.replace(&tz.to_string(), "");
+ }
let lines = if color {
- log_sanitizer::colorize_logs(i)
+ log_sanitizer::colorize_logs(&i)
} else if raw {
- log_sanitizer::raw(i)
+ log_sanitizer::raw(&i)
} else {
- log_sanitizer::remove_ansi(i)
+ log_sanitizer::remove_ansi(&i)
};
- container.logs.items.push(ListItem::new(lines));
+ container.logs.insert(ListItem::new(lines), tz);
}
// Set the logs selected row for each container
// Either when no long currently selected, or currently selected (before updated) is already at end
- if container.logs.state.selected().is_none()
- || container.logs.state.selected().map_or(1, |f| f + 1) == current_len
+ if container.logs.state().selected().is_none()
+ || container.logs.state().selected().map_or(1, |f| f + 1) == current_len
{
container.logs.end();
}
}
- self.logs_parsed = true;
}
}
diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs
index 7e89b90..c700654 100644
--- a/src/docker_data/mod.rs
+++ b/src/docker_data/mod.rs
@@ -3,7 +3,7 @@ use bollard::{
service::ContainerSummary,
Docker,
};
-use futures_util::{Future, StreamExt};
+use futures_util::StreamExt;
use parking_lot::Mutex;
use std::{
collections::HashMap,
@@ -33,7 +33,7 @@ enum SpawnId {
/// Cpu & Mem stats take twice as long as the update interval to get a value, so will have two being executed at the same time
/// SpawnId::Stats takes container_id and binate value to enable both cycles of the same container_id to be inserted into the hashmap
-/// Binate value is toggled when all join handles have been spawned off
+/// Binate value is toggled when all handles have been spawned off
/// Also effectively means that if the docker_update interval minimum will be 1000ms
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
enum Binate {
@@ -56,7 +56,6 @@ pub struct DockerData {
binate: Binate,
docker: Arc,
gui_state: Arc>,
- initialised: bool,
is_running: Arc,
receiver: Receiver,
spawns: Arc>>>,
@@ -94,12 +93,12 @@ impl DockerData {
/// don't take &self, so that can tokio::spawn into it's own thread
/// remove if from spawns hashmap when complete
async fn update_container_stat(
+ app_data: Arc>,
docker: Arc,
id: ContainerId,
- app_data: Arc>,
is_running: bool,
- spawns: Arc>>>,
spawn_id: SpawnId,
+ spawns: Arc>>>,
) {
let mut stream = docker
.stats(
@@ -156,18 +155,18 @@ impl DockerData {
let docker = Arc::clone(&self.docker);
let app_data = Arc::clone(&self.app_data);
let spawns = Arc::clone(&self.spawns);
- let spawn_key = SpawnId::Stats((id.clone(), self.binate));
+ let spawn_id = SpawnId::Stats((id.clone(), self.binate));
self.spawns
.lock()
- .entry(spawn_key.clone())
+ .entry(spawn_id.clone())
.or_insert_with(|| {
tokio::spawn(Self::update_container_stat(
+ app_data,
docker,
id.clone(),
- app_data,
*is_running,
+ spawn_id,
spawns,
- spawn_key,
))
});
}
@@ -223,19 +222,17 @@ impl DockerData {
}
/// Update single container logs
- /// don't take &self, so that can tokio::spawn into it's own thread
- /// remove if from spawns hashmap when complete
+ /// remove it from spawns hashmap when complete
async fn update_log(
+ app_data: Arc>,
docker: Arc,
id: ContainerId,
- timestamps: bool,
since: u64,
- app_data: Arc>,
spawns: Arc>>>,
) {
let options = Some(LogsOptions:: {
stdout: true,
- timestamps,
+ timestamps: true,
since: i64::try_from(since).unwrap_or_default(),
..Default::default()
});
@@ -243,16 +240,14 @@ impl DockerData {
let mut logs = docker.logs(id.get(), options);
let mut output = vec![];
- while let Some(value) = logs.next().await {
- if let Ok(data) = value {
- let log_string = data.to_string();
- if !log_string.trim().is_empty() {
- output.push(log_string);
- }
+ while let Some(Ok(value)) = logs.next().await {
+ let data = value.to_string();
+ if !data.trim().is_empty() {
+ output.push(data);
}
}
spawns.lock().remove(&SpawnId::Log(id.clone()));
- app_data.lock().update_log_by_id(&output, &id);
+ app_data.lock().update_log_by_id(output, &id);
}
/// Update all logs, spawn each container into own tokio::spawn thread
@@ -264,14 +259,7 @@ impl DockerData {
let key = SpawnId::Log(id.clone());
self.spawns.lock().insert(
key,
- tokio::spawn(Self::update_log(
- docker,
- id.clone(),
- self.args.timestamp,
- 0,
- app_data,
- spawns,
- )),
+ tokio::spawn(Self::update_log(app_data, docker, id.clone(), 0, spawns)),
);
}
}
@@ -290,11 +278,10 @@ impl DockerData {
let app_data = Arc::clone(&self.app_data);
let spawns = Arc::clone(&self.spawns);
tokio::spawn(Self::update_log(
+ app_data,
docker,
container.id.clone(),
- self.args.timestamp,
container.last_updated,
- app_data,
spawns,
))
});
@@ -305,8 +292,8 @@ impl DockerData {
}
/// Animate the loading icon
- async fn loading_spin(&mut self, loading_uuid: Uuid) -> JoinHandle<()> {
- let gui_state = Arc::clone(&self.gui_state);
+ async fn loading_spin(loading_uuid: Uuid, gui_state: &Arc>) -> JoinHandle<()> {
+ let gui_state = Arc::clone(&gui_state);
tokio::spawn(async move {
loop {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
@@ -316,89 +303,106 @@ impl DockerData {
}
/// Stop the loading_spin function, and reset gui loading status
- fn stop_loading_spin(&mut self, handle: &JoinHandle<()>, loading_uuid: Uuid) {
+ fn stop_loading_spin(
+ gui_state: &Arc>,
+ handle: &JoinHandle<()>,
+ loading_uuid: Uuid,
+ ) {
handle.abort();
- self.gui_state.lock().remove_loading(loading_uuid);
+ gui_state.lock().remove_loading(loading_uuid);
}
/// Initialize docker container data, before any messages are received
async fn initialise_container_data(&mut self) {
self.gui_state.lock().status_push(Status::Init);
let loading_uuid = Uuid::new_v4();
- let loading_spin = self.loading_spin(loading_uuid).await;
+ let loading_spin = Self::loading_spin(loading_uuid, &Arc::clone(&self.gui_state)).await;
let all_ids = self.update_all_containers().await;
self.update_all_container_stats(&all_ids);
- // Maybe only do a single one at first?
self.init_all_logs(&all_ids);
- if all_ids.is_empty() {
- self.initialised = true;
- }
-
// wait until all logs have initialised
- while !self.initialised {
+ while !self.app_data.lock().initialised(&all_ids) {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
- self.initialised = self.app_data.lock().initialised(&all_ids);
}
self.gui_state.lock().status_del(Status::Init);
- self.stop_loading_spin(&loading_spin, loading_uuid);
+ Self::stop_loading_spin(&self.gui_state, &loading_spin, loading_uuid);
}
/// Set the global error as the docker error, and set gui_state to error
- fn set_error(&mut self, error: DockerControls) {
- self.app_data
- .lock()
- .set_error(AppError::DockerCommand(error));
- self.gui_state.lock().status_push(Status::Error);
- }
-
- /// Execute a docker command, will start and stop the loading spinner, and set correct error
- async fn exec_docker(
- &mut self,
- docker_fn: impl Future