diff --git a/.github/workflows/create_release_and_build.yml b/.github/workflows/create_release_and_build.yml index 0d629ae..2a4b26f 100644 --- a/.github/workflows/create_release_and_build.yml +++ b/.github/workflows/create_release_and_build.yml @@ -7,16 +7,8 @@ jobs: deploy: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@master - - # cache some rust data? - - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + - name: Checkout + uses: actions/checkout@v3 # Build for linux x86_64 - name: build release linux_x86_64 @@ -72,6 +64,24 @@ jobs: - name: compress windows_x86_64 binary run: zip -j ./oxker_windows_x86_64.zip target/x86_64-pc-windows-gnu/release/oxker.exe + # Build images for Dockerhub + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - uses: docker/setup-buildx-action@v2 + id: buildx + with: + install: true + - name: Build for Docker Hub + run: | + docker build --platform linux/arm/v6,linux/arm64,linux/amd64 \ + -t ${{ secrets.DOCKERHUB_USERNAME }}/oxker:latest \ + --push \ + -f containerised/Dockerfile . + - name: Release uses: softprops/action-gh-release@v1 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index b504e4c..f9230af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,11 @@ + dependencies updated, [a3168daa3f769a6747dfbe61103073a7e80a1485], [78e59160bb6a978ee80e3a99eb72f051fb64e737] ### Fixes -+ limit image name to 64 chars max, [b8f7763dd5ac7d0361dd7bfc1dad40f50ee95ae1] + devcontainer updated, [3bde4f5629539cab3dbb57556663ab81685f9d7a] ### Features + derive Eq where appropriate, [d7c2601f959bc12a64cd25cef59c837e1e8c2b2a] ++ containerize self, github action to build and push to Docker Hub, [] + ignore containers 'oxker' containers, [1be9f52ad4a68f93142784e9df630c59cdec0a79] ### Refactors diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 30f795e..0000000 --- a/Dockerfile +++ /dev/null @@ -1,103 +0,0 @@ -# FROM debian:bullseye-slim -# FROM -FROM alpine:latest -# FROM scratch - -# DOCKER_GUID=1000 \ - # DOCKER_UID=1000 \ - # DOCKER_TIME_CONT=America \ - # DOCKER_TIME_CITY=New_York \ -# ARG DOCKER_APP_USER=oxker \ - # DOCKER_APP_GROUP=docker - -# ENV TZ=${DOCKER_TIME_CONT}/${DOCKER_TIME_CITY} - -# RUN apt-get update \ - # && apt-get install -y ca-certificates wget \ - # && update-ca-certificates \ -# RUN groupadd ${DOCKER_APP_GROUP} -# RUN useradd --no-create-home --no-log-init ${DOCKER_APP_USER} - # && mkdir /healthcheck /logs \ - # && chown ${DOCKER_APP_USER}:${DOCKER_APP_GROUP} /logs - -WORKDIR /app - -# COPY --chown=${DOCKER_APP_USER}:${DOCKER_APP_GROUP} docker/healthcheck/health_api.sh /healthcheck - -# Copy from local release destination -# COPY --chown=${DOCKER_APP_USER} target/release/oxker /app/ -# COPY target/release/oxker . -# RUN mkdir app -COPY /target/x86_64-unknown-linux-musl/release/oxker ./ -COPY ./start_oxker.sh ./ -RUN chmod +x /app/start_oxker.sh - -# Use an unprivileged user -# USER ${DOCKER_APP_USER} -ENV RUST_BACKTRACE=full -# ENTRYPOINT ["./oxker" ] -# CMD [ "./oxker"] -ENTRYPOINT ["/app/start_oxker.sh"] - -# docker run --rm -ti \ -# --name=ctop \ -# --volume /var/run/docker.sock:/var/run/docker.sock:ro \ -# # quay.io/vektorlab/ctop:latest - - -# docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro oxker - -# docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro ghcr.io/mrjackwills/oxker:latest -# could get arch, and then download appropoatley from github? - -# FROM rust:latest as cargo-build - -# WORKDIR /build -# ENV RUSTFLAGS="-C target-feature=+crt-static" - -# COPY Cargo* ./build -# COPY src/ ./build - -# RUN cargo build --release --target x86_64-unknown-linux-gnu - -# ##################################### - - -# ##################################### - -# FROM scratch - -# COPY --from=cargo-build /build/target/x86_64-unknown-linux-gnu/release/oxker /oxker - -# ENTRYPOINT [ "/oxker" ] - -# FROM rust:latest AS build -# WORKDIR /oxker_build - -# # Download the target for static linking. -# RUN rustup target add x86_64-unknown-linux-musl - -# # Create a dummy project and build the app's dependencies. -# # If the Cargo.toml or Cargo.lock files have not changed, -# # we can use the docker build cache and skip these (typically slow) steps. -# RUN USER=root cargo new oxker --bin -# WORKDIR /oxker_build -# COPY Cargo.toml Cargo.lock ./ -# # CMD ["sleep", "6000"] - -# # RUN cargo build --release - -# # Copy the source and build the application. -# COPY src ./src/ -# RUN cargo install --target x86_64-unknown-linux-musl --path . - -# # Copy the statically-linked binary into a scratch container. -# FROM scratch -# COPY --from=build /oxker_build/bin/oxker . -# # USER 1000 -# CMD ["./oxker"] - -# cross build --target x86_64-unknown-linux-musl --release - -# rustup target add x86_64-unknown-linux-musl -# cargo build --release --target=x86_64-unknown-linux-musl \ No newline at end of file diff --git a/README.md b/README.md index db64461..284f335 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- +

@@ -20,6 +20,12 @@

+## Run via Docker + +Now published on Docker Hub, with images built for `linux/amd64`, `linux/arm64v8`, and `linux/armv6` + +`docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro mrjackwills/oxker:latest` + ## Download & install diff --git a/containerised/DOCKERHUB_README.md b/containerised/DOCKERHUB_README.md new file mode 100644 index 0000000..d8ef143 --- /dev/null +++ b/containerised/DOCKERHUB_README.md @@ -0,0 +1,26 @@ +

+ +

+ +

+

oxker

+
+ A simple tui to view & control docker containers +
+

+ +

+ + + +

+ +## Run + +Images built for `linux/amd64`, `linux/arm64v8`, and `linux/armv6` + +`docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro mrjackwills/oxker:latest` + +## Help + +visit the Github repo \ No newline at end of file diff --git a/containerised/Dockerfile b/containerised/Dockerfile new file mode 100644 index 0000000..18e9953 --- /dev/null +++ b/containerised/Dockerfile @@ -0,0 +1,59 @@ +############# +## Builder ## +############# + +FROM --platform=linux/amd64 rust:slim as builder + +ARG TARGETARCH + +# These are build platform depandant, but will be ignored if not needed +ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER="aarch64-linux-gnu-gcc" +ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-C target-feature=+crt-static -C link-arg=-lgcc" +ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_MUSLEABIHF_LINKER="arm-linux-gnueabihf-ld" + +COPY ./containerised/platform.sh . + +RUN chmod +x ./platform.sh && ./platform.sh + +RUN apt-get update && apt-get install $(cat /.compiler) -y + +WORKDIR /usr/src + +# Create blank project +RUN cargo new oxker + +# We want dependencies cached, so copy those first +COPY Cargo.* /usr/src/oxker/ + +# Set the working directory +WORKDIR /usr/src/oxker + +# Install target platform (Cross-Compilation) +RUN rustup target add $(cat /.platform) + +# This is a dummy build to get the dependencies cached +RUN cargo build --target $(cat /.platform) --release + +# Now copy in the rest of the sources +COPY src /usr/src/oxker/src/ + +## Touch main.rs to prevent cached release build +RUN touch /usr/src/oxker/src/main.rs + +# This is the actual application build +RUN cargo build --release --target $(cat /.platform) + +RUN cp /usr/src/oxker/target/$(cat /.platform)/release/oxker / + +############# +## Runtime ## +############# + +FROM alpine:latest AS runtime + +# Copy application binary from builder image +COPY --from=builder /oxker /usr/local/bin +COPY ./containerised/start_oxker.sh ./ + +# Run the application +ENTRYPOINT [ "./start_oxker.sh"] diff --git a/containerised/Dockerfile_dev b/containerised/Dockerfile_dev new file mode 100644 index 0000000..ea142ab --- /dev/null +++ b/containerised/Dockerfile_dev @@ -0,0 +1,15 @@ +############# +## Runtime ## +############# + +FROM alpine:latest AS runtime + +# Copy application binary from builder image +COPY ./target/x86_64-unknown-linux-musl/release/oxker /usr/local/bin +COPY ./containerised/start_oxker.sh ./ + +# Run the application +ENTRYPOINT [ "./start_oxker.sh"] + +# 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_dev . && docker run --rm -it --volume /var/run/docker.sock:/var/run/docker.sock:ro oxker_dev \ No newline at end of file diff --git a/containerised/platform.sh b/containerised/platform.sh new file mode 100644 index 0000000..393769a --- /dev/null +++ b/containerised/platform.sh @@ -0,0 +1,18 @@ +#!/bin/sh +# Used in Docker build to set platform dependent variables + +case $TARGETARCH in + + "amd64") + echo "x86_64-unknown-linux-musl" > /.platform + echo "" > /.compiler + ;; + "arm64") + echo "aarch64-unknown-linux-musl" > /.platform + echo "gcc-aarch64-linux-gnu" > /.compiler + ;; + "arm") + echo "arm-unknown-linux-musleabihf" > /.platform + echo "gcc-arm-linux-gnueabihf" > /.compiler + ;; +esac \ No newline at end of file diff --git a/containerised/start_oxker.sh b/containerised/start_oxker.sh new file mode 100755 index 0000000..d0563c0 --- /dev/null +++ b/containerised/start_oxker.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +# 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/src/app_error.rs b/src/app_error.rs index 1f2d889..767b204 100644 --- a/src/app_error.rs +++ b/src/app_error.rs @@ -16,17 +16,17 @@ pub enum AppError { /// Convert errors into strings to display impl fmt::Display for AppError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let disp = match self { - Self::DockerConnect => "Unable to access docker daemon".to_owned(), - Self::DockerInterval => "Docker update interval needs to be greater than 0".to_owned(), - Self::InputPoll => "Unable to poll user input".to_owned(), - Self::Terminal => "Unable to draw to terminal".to_owned(), - Self::DockerCommand(s) => format!("Unable to {} container", s), + match self { + Self::DockerConnect => write!(f, "Unable to access docker daemon"), + Self::DockerInterval => write!(f, "Docker update interval needs to be greater than 0"), + Self::InputPoll => write!(f, "Unable to poll user input"), + Self::Terminal => write!(f, "Unable to draw to terminal"), + Self::DockerCommand(s) => write!(f, "Unable to {} container", s), Self::MouseCapture(x) => { let reason = if *x { "en" } else { "dis" }; - format!("Unable to {}able mouse capture", reason) + write!(f, "Unbale to {}able mouse capture", reason) } - }; - write!(f, "{}", disp) + } + } } diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index c49182c..2675c6c 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -193,12 +193,13 @@ impl DockerData { let current_sort = self.app_data.lock().get_sorted(); self.app_data.lock().set_sorted(current_sort); + // Just get the containers that are currently running, no point updating info on paused or dead containers output .iter() .filter_map(|i| { i.id.as_ref().map(|id| { ( - i.state.as_ref().unwrap_or(&String::new()) == "running", + i.state == Some("running".to_owned()), id.clone(), ) }) @@ -331,53 +332,53 @@ impl DockerData { match message { DockerMessage::Pause(id) => { let loading_spin = self.loading_spin().await; - docker.pause_container(&id).await.unwrap_or_else(|_| { + if docker.pause_container(&id).await.is_err() { app_data .lock() .set_error(AppError::DockerCommand(DockerControls::Pause)); - }); + }; self.stop_loading_spin(&loading_spin); } DockerMessage::Restart(id) => { let loading_spin = self.loading_spin().await; - docker + if docker .restart_container(&id, None) .await - .unwrap_or_else(|_| { + .is_err() { app_data .lock() .set_error(AppError::DockerCommand(DockerControls::Restart)); - }); + }; self.stop_loading_spin(&loading_spin); } DockerMessage::Start(id) => { let loading_spin = self.loading_spin().await; - docker + if docker .start_container(&id, None::>) .await - .unwrap_or_else(|_| { + .is_err() { app_data .lock() .set_error(AppError::DockerCommand(DockerControls::Start)); - }); + }; self.stop_loading_spin(&loading_spin); } DockerMessage::Stop(id) => { let loading_spin = self.loading_spin().await; - docker.stop_container(&id, None).await.unwrap_or_else(|_| { + if docker.stop_container(&id, None).await.is_err() { app_data .lock() .set_error(AppError::DockerCommand(DockerControls::Stop)); - }); + }; self.stop_loading_spin(&loading_spin); } DockerMessage::Unpause(id) => { let loading_spin = self.loading_spin().await; - docker.unpause_container(&id).await.unwrap_or_else(|_| { + if docker.unpause_container(&id).await.is_err() { app_data .lock() .set_error(AppError::DockerCommand(DockerControls::Unpause)); - }); + }; self.stop_loading_spin(&loading_spin); self.update_everything().await; } diff --git a/src/main.rs b/src/main.rs index 8015736..37b6919 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,6 +100,7 @@ async fn main() { .unwrap_or(()); } else { loop { + // TODO this needs to be improved to display something useful info!("in debug mode"); tokio::time::sleep(std::time::Duration::from_millis(5000)).await; } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 9a529fd..ba02a91 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -109,7 +109,7 @@ async fn run_app( if terminal.draw(|f| ui(f, &app_data, &gui_state)).is_err() { return Err(AppError::Terminal); } - if crossterm::event::poll(input_poll_rate).unwrap_or_default() { + if crossterm::event::poll(input_poll_rate).unwrap_or(false) { if let Ok(event) = event::read() { if let Event::Key(key) = event { sender diff --git a/start_oxker.sh b/start_oxker.sh deleted file mode 100755 index 10a03d1..0000000 --- a/start_oxker.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -set -e - -# No idea why this is sloving my issue, or even where the issue is originally coming from -sleep 1 - -exec ./oxker "$@" \ No newline at end of file