A simple tui to view & control docker containers
diff --git a/containerised/Dockerfile b/containerised/Dockerfile
index 525ea7d..9d0fe10 100644
--- a/containerised/Dockerfile
+++ b/containerised/Dockerfile
@@ -51,10 +51,12 @@ RUN cp /usr/src/oxker/target/$(cat /.platform)/release/oxker /
FROM alpine:latest AS runtime
+# Set an ENV that we're running in a container, so that the application can sleep for 250ms at start
+ENV OXKER_RUNTIME=container
+
# Copy application binary from builder image
COPY --from=builder /oxker /usr/local/bin
-COPY ./containerised/start_oxker.sh ./
# Run the application
# this is used in the application itself, to stop itself show when running from a docker container, so DO NOT EDIT
-ENTRYPOINT [ "./start_oxker.sh"]
+ENTRYPOINT [ "./app/oxker"]
diff --git a/containerised/Dockerfile_dev b/containerised/Dockerfile_dev
index 4a91c38..77a5522 100644
--- a/containerised/Dockerfile_dev
+++ b/containerised/Dockerfile_dev
@@ -1,16 +1,23 @@
#############
## Runtime ##
#############
+FROM scratch
-FROM alpine:latest AS runtime
+# Set env that we're running in a container, so that the application can sleep for 250ms at start
+ENV OXKER_RUNTIME=container
# Copy application binary from builder image
-COPY ./target/x86_64-unknown-linux-musl/release/oxker /usr/local/bin
-COPY ./containerised/start_oxker.sh ./
+COPY ./target/x86_64-unknown-linux-musl/release/oxker /app/
# Run the application
# this is used in the application itself, to stop itself show when running from a docker container, so DO NOT EDIT
-ENTRYPOINT [ "./start_oxker.sh"]
+ENTRYPOINT [ "./app/oxker"]
+
+# Dev build for testing
+# docker build -t oxker_dev -f Dockerfile . && docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro oxker_dev
+
+# Dev build one liner, x86 host
+# docker image prune -a; cargo build --release --target x86_64-unknown-linux-musl && docker build -t oxker_dev -f containerised/Dockerfile_dev . && docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro oxker_dev
## One liner to build musl program, build docker image, then execute the image
# cargo build --release --target x86_64-unknown-linux-musl && docker build -t oxker_dev -f containerised/Dockerfile . && docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro oxker_dev
diff --git a/containerised/start_oxker.sh b/containerised/start_oxker.sh
deleted file mode 100755
index 7ac5fa3..0000000
--- a/containerised/start_oxker.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-set -e
-
-# Without this sleep, the docker image will instantly close
-# No idea why this is solving my issue, or even where the issue is originally coming from
-sleep .1
-
-exec /usr/local/bin/oxker "$@"
\ No newline at end of file
diff --git a/create_release.sh b/create_release.sh
index f04c721..75484be 100755
--- a/create_release.sh
+++ b/create_release.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# rust create_release
-# v0.1.2
+# v0.2.1
STAR_LINE='****************************************'
CWD=$(pwd)
@@ -176,12 +176,16 @@ cargo_test () {
# This will download GB's of docker images
cargo_build () {
cargo install cross
+ echo -e "${YELLOW}cargo build --release${RESET}"
cargo build --release
ask_continue
+ echo -e "${YELLOW}cross build --target aarch64-unknown-linux-musl --release${RESET}"
cross build --target aarch64-unknown-linux-musl --release
ask_continue
+ echo -e "${YELLOW}cross build --target arm-unknown-linux-musleabihf --release${RESET}"
cross build --target arm-unknown-linux-musleabihf --release
ask_continue
+ echo -e "${YELLOW}cross build --target x86_64-pc-windows-gnu --release${RESET}"
cross build --target x86_64-pc-windows-gnu --release
ask_continue
}
@@ -190,12 +194,22 @@ cargo_build () {
release_continue () {
echo -e "\n${PURPLE}$1${RESET}"
ask_continue
-
}
+
+# Check repository for typos
+check_typos () {
+ echo -e "\n${PURPLE}check typos${RESET}"
+ typos
+ ask_continue
+}
+
# Full flow to create a new release
release_flow() {
+ check_typos
+
check_git
get_git_remote_url
+
cargo_test
cargo_build
@@ -227,8 +241,10 @@ release_flow() {
release_continue "git checkout main"
git checkout main
- release_continue "git merge --no-ff \"${RELEASE_BRANCH}\" -m \"chore: merge ${RELEASE_BRANCH} into main\""
+ echo -e "${PURPLE}git merge --no-ff \"${RELEASE_BRANCH}\" -m \"chore: merge ${RELEASE_BRANCH} into main\"${RESET}"
git merge --no-ff "$RELEASE_BRANCH" -m "chore: merge ${RELEASE_BRANCH} into main"
+ echo -e "\n${PURPLE}cargo check${RESET}\n"
+ cargo check
release_continue "git tag -am \"${RELEASE_BRANCH}\" \"$NEW_TAG_WITH_V\""
git tag -am "${RELEASE_BRANCH}" "$NEW_TAG_WITH_V"
diff --git a/src/app_data/container_state.rs b/src/app_data/container_state.rs
index efa2d81..aedc613 100644
--- a/src/app_data/container_state.rs
+++ b/src/app_data/container_state.rs
@@ -377,8 +377,8 @@ impl fmt::Display for LogsTz {
}
/// 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
+/// so if we store the timestamp separately in a HashSet, we can then check if we should insert a log line into the
+/// stateful list dependent on whethere the timestamp is in the HashSet or not
#[derive(Debug, Clone)]
pub struct Logs {
logs: StatefulList
>,
diff --git a/src/app_data/mod.rs b/src/app_data/mod.rs
index 0837c24..441c23a 100644
--- a/src/app_data/mod.rs
+++ b/src/app_data/mod.rs
@@ -376,7 +376,7 @@ impl AppData {
.map(|i| i.logs.state())
}
- /// Error realted methods
+ /// Error related methods
/// return single app_state error
pub const fn get_error(&self) -> Option {
diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs
index 43a2124..ad0c500 100644
--- a/src/docker_data/mod.rs
+++ b/src/docker_data/mod.rs
@@ -54,6 +54,7 @@ pub struct DockerData {
app_data: Arc>,
args: CliArgs,
binate: Binate,
+ containerised: bool,
docker: Arc,
gui_state: Arc>,
is_running: Arc,
@@ -62,7 +63,7 @@ pub struct DockerData {
}
impl DockerData {
- /// Use docker stats to caluclate current cpu usage
+ /// Use docker stats to calculate current cpu usage
#[allow(clippy::cast_precision_loss)]
fn calculate_usage(stats: &Stats) -> f64 {
let mut cpu_percentage = 0.0;
@@ -175,7 +176,7 @@ impl DockerData {
/// Get all current containers, handle into ContainerItem in the app_data struct rather than here
/// Just make sure that items sent are guaranteed to have an id
- /// Will ignore any container that uses `./start_oxker.sh` as an entry point, unless the `-s` flag is set
+ /// If in a containerised runtime, will ignore any container that uses the q`./app/oxker` as an entry point, unless the `-s` flag is set
pub async fn update_all_containers(&mut self) -> Vec<(bool, ContainerId)> {
let containers = self
.docker
@@ -190,9 +191,10 @@ impl DockerData {
.into_iter()
.filter_map(|f| match f.id {
Some(_) => {
- if f.command
- .as_ref()
- .map_or(false, |c| c.starts_with(ENTRY_POINT))
+ if self.containerised
+ && f.command
+ .as_ref()
+ .map_or(false, |c| c.starts_with(ENTRY_POINT))
&& self.args.show_self
{
None
@@ -414,6 +416,7 @@ impl DockerData {
/// Initialise self, and start the message receiving loop
pub async fn init(
app_data: Arc>,
+ containerised: bool,
docker: Docker,
docker_rx: Receiver,
gui_state: Arc>,
@@ -423,6 +426,7 @@ impl DockerData {
if app_data.lock().get_error().is_none() {
let mut inner = Self {
app_data,
+ containerised,
args,
binate: Binate::One,
docker: Arc::new(docker),
diff --git a/src/main.rs b/src/main.rs
index 9e3fdfe..56b198f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,10 @@
#![forbid(unsafe_code)]
-#![warn(clippy::unused_async, clippy::unwrap_used, clippy::expect_used)]
+#![warn(
+ clippy::expect_used,
+ clippy::todo,
+ clippy::unused_async,
+ clippy::unwrap_used
+)]
// Warning - These are indeed pedantic
#![warn(clippy::pedantic)]
#![warn(clippy::nursery)]
@@ -33,16 +38,35 @@ use ui::{create_ui, GuiState, Status};
use crate::docker_data::DockerMessage;
-const ENTRY_POINT: &str = "./start_oxker.sh";
+// this is the entry point when running as a Docker Container, and is used, in conjunction with the `CONTAINER_ENV` ENV, to check if we are running as a Docker Container
+const ENTRY_POINT: &str = "./app/oxker";
+const ENV_KEY: &str = "OXKER_RUNTIME";
+const ENV_VALUE: &str = "container";
+/// Enable tracing, only really used in debug mode, for now
/// write to file if `-g` is set?
fn setup_tracing() {
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
}
+/// An ENV is set in the ./containerised/Dockerfile, if this is ENV found, then sleep for 250ms, else the container, for as yet unknown reasons, will close immediately
+/// returns a bool, so that the `update_all_containers()` won't bother to check the entry point unless running via a container
+fn check_if_containerised() -> bool {
+ if std::env::vars()
+ .into_iter()
+ .any(|x| x == (ENV_KEY.into(), ENV_VALUE.into()))
+ {
+ std::thread::sleep(std::time::Duration::from_millis(250));
+ true
+ } else {
+ false
+ }
+}
+
/// Create docker daemon handler, and only spawn up the docker data handler if a ping returns non-error
async fn docker_init(
app_data: &Arc>,
+ containerised: bool,
docker_rx: Receiver,
gui_state: &Arc>,
is_running: &Arc,
@@ -53,7 +77,12 @@ async fn docker_init(
let gui_state = Arc::clone(gui_state);
let is_running = Arc::clone(is_running);
tokio::spawn(DockerData::init(
- app_data, docker, docker_rx, gui_state, is_running,
+ app_data,
+ containerised,
+ docker,
+ docker_rx,
+ gui_state,
+ is_running,
));
} else {
app_data.lock().set_error(AppError::DockerConnect);
@@ -87,7 +116,10 @@ fn handler_init(
#[tokio::main]
async fn main() {
+ let containerised = check_if_containerised();
+
setup_tracing();
+
let args = CliArgs::new();
let app_data = Arc::new(Mutex::new(AppData::default(args)));
let gui_state = Arc::new(Mutex::new(GuiState::default()));
@@ -95,7 +127,7 @@ async fn main() {
let (docker_sx, docker_rx) = tokio::sync::mpsc::channel(16);
let (input_sx, input_rx) = tokio::sync::mpsc::channel(16);
- docker_init(&app_data, docker_rx, &gui_state, &is_running).await;
+ docker_init(&app_data, containerised, docker_rx, &gui_state, &is_running).await;
handler_init(&app_data, &docker_sx, &gui_state, input_rx, &is_running);
diff --git a/src/ui/draw_blocks.rs b/src/ui/draw_blocks.rs
index 9e1a0fe..88010c3 100644
--- a/src/ui/draw_blocks.rs
+++ b/src/ui/draw_blocks.rs
@@ -328,7 +328,7 @@ fn make_chart<'a, T: Stats + Display>(
}
/// Draw heading bar at top of program, always visible
-/// TODO Should seperate into loading icon/headers/help functions
+/// TODO Should separate into loading icon/headers/help functions
#[allow(clippy::too_many_lines)]
pub fn heading_bar(
area: Rect,
@@ -510,7 +510,7 @@ pub fn help_box(f: &mut Frame<'_, B>) {
);
help_text.push_str("\n ( q ) to quit at any time");
help_text.push_str("\n mouse scrolling & clicking also available");
- help_text.push_str("\n\n currenty an early work in progress, all and any input appreciated");
+ help_text.push_str("\n\n currently an early work in progress, all and any input appreciated");
help_text.push_str(format!("\n {}", REPO.trim()).as_str());
// Find the maximum line widths & height
@@ -527,7 +527,7 @@ pub fn help_box(f: &mut Frame<'_, B>) {
.block(Block::default())
.alignment(Alignment::Center);
- let description_paragrpah = Paragraph::new(description_text.as_str())
+ let description_paragraph = Paragraph::new(description_text.as_str())
.style(Style::default().bg(Color::Magenta).fg(Color::Black))
.block(Block::default())
.alignment(Alignment::Center);
@@ -566,7 +566,7 @@ pub fn help_box(f: &mut Frame<'_, B>) {
// Order is important here
f.render_widget(Clear, area);
f.render_widget(name_paragraph, split_popup[0]);
- f.render_widget(description_paragrpah, split_popup[1]);
+ f.render_widget(description_paragraph, split_popup[1]);
f.render_widget(help_paragraph, split_popup[2]);
f.render_widget(block, area);
}
diff --git a/src/ui/gui_state.rs b/src/ui/gui_state.rs
index 923c15a..ead3245 100644
--- a/src/ui/gui_state.rs
+++ b/src/ui/gui_state.rs
@@ -273,7 +273,7 @@ impl GuiState {
self.is_loading.insert(uuid);
}
- /// If is_loading has any entries, return the current loading_icon, else an emtpy string
+ /// If is_loading has any entries, return the current loading_icon, else an empty string
pub fn get_loading(&mut self) -> String {
if self.is_loading.is_empty() {
String::from(" ")