Merge branch 'feat/docker' into dev
This commit is contained in:
@@ -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:
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
-103
@@ -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
|
||||
@@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img src='./.github/logo.svg' width='125px'/>
|
||||
<img src='./.github/logo.svg' width='100px'/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -20,6 +20,12 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Run via Docker
|
||||
|
||||
Now published on <a href='https://hub.docker.com/r/mrjackwills/oxker' target='_blank' rel='noopener noreferrer'>Docker Hub</a>, 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
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<p align="center">
|
||||
<img src='https://raw.githubusercontent.com/mrjackwills/oxker/main/.github/logo.svg' width='100px'/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<h1 align="center">oxker</h1>
|
||||
<div align="center">
|
||||
A simple tui to view & control docker containers
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://raw.githubusercontent.com/mrjackwills/oxker/main/.github/screenshot_01.jpg" target='_blank' rel='noopener noreferrer'>
|
||||
<img src='https://raw.githubusercontent.com/mrjackwills/oxker/main/.github/screenshot_01.jpg' width='60%'/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## 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<a href="https://github.com/mrjackwills/oxker" target='_blank' rel='noopener noreferrer'> Github repo</a>
|
||||
@@ -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"]
|
||||
@@ -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
|
||||
@@ -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
|
||||
Executable
+7
@@ -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 "$@"
|
||||
+10
-10
@@ -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, "{}", disp)
|
||||
write!(f, "Unbale to {}able mouse capture", reason)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+14
-13
@@ -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::<StartContainerOptions<String>>)
|
||||
.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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ async fn run_app<B: Backend + Send>(
|
||||
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
|
||||
|
||||
@@ -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 "$@"
|
||||
Reference in New Issue
Block a user