diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5ed537b..3fa91c2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,20 +10,34 @@ jobs: build: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 - - name: Build - uses: redhat-actions/buildah-build@v2 + - name: Clone repo + uses: actions/checkout@v4 + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Registry + uses: docker/login-action@v3 with: - image: ${{ github.actor }}/${{ github.event.repository.name }} - tags: ${{ github.ref_name }} - containerfiles: | - ./Containerfile - - name: Push - uses: redhat-actions/push-to-registry@v2 - with: - image: ${{ github.actor }}/${{ github.event.repository.name }} - tags: ${{ github.ref_name }} - extra-args: --compression-format zstd:chunked registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Build and push base container + uses: docker/build-push-action@v5 + with: + context: ./containers/base + file: ./containers/base/Containerfile + push: true + tags: ghcr.io/${{ github.actor }}/base:latest + - name: Build and push go container + uses: docker/build-push-action@v5 + with: + context: ./containers/go + file: ./containers/go/Containerfile + push: true + tags: ghcr.io/${{ github.actor }}/go:latest + - name: Build and push kube container + uses: docker/build-push-action@v5 + with: + context: ./containers/kube + file: ./containers/kube/Containerfile + push: true + tags: ghcr.io/${{ github.actor }}/kube:latest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9be70be --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +state/last-name diff --git a/Containerfile b/Containerfile deleted file mode 100644 index f138cb3..0000000 --- a/Containerfile +++ /dev/null @@ -1,35 +0,0 @@ -# ========================================= # -# Containerfile v1.0; job79 # -# Configure and setup a neovim devcontainer # -# for go and nodejs development. # -# ========================================= # -FROM quay.io/fedora/fedora:42 - -# === setup system === -RUN dnf update -y && \ - dnf copr enable -y atim/lazygit && \ - dnf -y install procps ping bash-completion \ - host-spawn dbus-launch zoxide \ - neovim awk jq unzip fd-find chafa lazygit \ - git go npm - -# === setup container user === -# Setup passwordless sudo. -RUN useradd -ms /bin/bash user && usermod -aG wheel user && sed -i '/NOPASSWD/s/^#//g' /etc/sudoers - -# Create empty /run/user/1000 dir for mounting sockets. -RUN mkdir /run/user/1000 && chown user:user /run/user/1000 - -# Setup container user. -USER user -WORKDIR /home/user -RUN mkdir .config .local .cache - -# Copy config into container. -COPY --chown=user:user config/bashrc .bashrc -COPY config/bin /usr/local/bin - -# === setup container === -# Set timezone inside container. -ENV TZ="Europe/Amsterdam" -VOLUME /home/user diff --git a/containers/base/Containerfile b/containers/base/Containerfile new file mode 100644 index 0000000..8252f6a --- /dev/null +++ b/containers/base/Containerfile @@ -0,0 +1,20 @@ +FROM quay.io/fedora/fedora:42 + +# === install system packages === +RUN dnf update -y && \ + dnf copr enable -y atim/lazygit && \ + dnf -y install procps ping bash-completion glibc-langpack-en \ + host-spawn dbus-launch \ + zoxide git npm neovim awk jq unzip fd-find chafa lazygit + +# === setup user === +RUN useradd -ms /bin/bash user && \ + usermod -aG wheel user && sed -i '/NOPASSWD/s/^#//g' /etc/sudoers && \ + mkdir -p /run/user/1000 && chown user:user /run/user/1000 + +USER user +WORKDIR /home/user +RUN mkdir .config .local .cache +COPY --chown=user:user config/bashrc .bashrc +COPY config/bin /usr/local/bin +VOLUME /home/user diff --git a/config/bashrc b/containers/base/config/bashrc similarity index 76% rename from config/bashrc rename to containers/base/config/bashrc index f6ea1a2..e1be1d4 100644 --- a/config/bashrc +++ b/containers/base/config/bashrc @@ -1,6 +1,6 @@ . /etc/bashrc -# === container enter logic === +# === container enter logic - cd to ENTER_DIR === ENTER_DIR="${ENTER_DIR/#\~/$HOME}" [ -d "$ENTER_DIR" ] && cd "$ENTER_DIR" @@ -10,7 +10,8 @@ export EDITOR=nvim \ XDG_RUNTIME_DIR=/run/user/1000 \ SSH_AUTH_SOCK=/run/user/1000/ssh-auth-sock \ DBUS_SESSION_BUS_ADDRESS="unix:path=/tmp/bus" \ - PS1='\[\e[30;46m\] container | \w \[\e[0;36m\]\[\e[m\] ' + PS1="\[\e[30;46m\] $CONTAINER_NAME | \w \[\e[0;36m\]\[\e[m\] " \ + TZ="Europe/Amsterdam" # === aliases and functions === alias vi=nvim diff --git a/config/bin/host b/containers/base/config/bin/host similarity index 100% rename from config/bin/host rename to containers/base/config/bin/host diff --git a/config/bin/podman b/containers/base/config/bin/podman similarity index 100% rename from config/bin/podman rename to containers/base/config/bin/podman diff --git a/config/bin/xdg-open b/containers/base/config/bin/xdg-open similarity index 100% rename from config/bin/xdg-open rename to containers/base/config/bin/xdg-open diff --git a/containers/go/Containerfile b/containers/go/Containerfile new file mode 100644 index 0000000..735ec5c --- /dev/null +++ b/containers/go/Containerfile @@ -0,0 +1,4 @@ +FROM ghcr.io/job79/base:latest +USER root +RUN dnf -y install go +USER user diff --git a/containers/go/config.sh b/containers/go/config.sh new file mode 100644 index 0000000..923eea6 --- /dev/null +++ b/containers/go/config.sh @@ -0,0 +1,3 @@ +for dir in "Code" "Documents" "Downloads" ".config/devcontainer"; do + arg "-v $HOME/$dir:/home/user/$dir" +done diff --git a/containers/kube/Containerfile b/containers/kube/Containerfile new file mode 100644 index 0000000..a3f49a0 --- /dev/null +++ b/containers/kube/Containerfile @@ -0,0 +1,4 @@ +FROM ghcr.io/job79/base:latest +USER root +RUN dnf -y install kubectl +USER user diff --git a/containers/kube/config.sh b/containers/kube/config.sh new file mode 100644 index 0000000..923eea6 --- /dev/null +++ b/containers/kube/config.sh @@ -0,0 +1,3 @@ +for dir in "Code" "Documents" "Downloads" ".config/devcontainer"; do + arg "-v $HOME/$dir:/home/user/$dir" +done diff --git a/enter.sh b/enter.sh index 2cd60ee..d3aa29c 100755 --- a/enter.sh +++ b/enter.sh @@ -1,38 +1,36 @@ -#!/bin/sh +#!/bin/bash # =============================================== # -# enter.sh v1.0; job79 # -# Enter into an existing or new dev container and # -# automatically handle dev container updates. # +# enter.sh v2.0; job79 # +# Dev container enter script. Handles setting up # +# different dev containers, resuming sessions and # +# automatic container updates. # # =============================================== # set -eu log() { printf '\e[%sm%s\e[0m %s\n' "${3:-36}" "${2:-○}" "$1"; } arg() { echo -n " $@"; } -# run_args returns the arguments required for the podman run -# command. +# run_args returns the podman run arguments required for +# starting a new container. run_args() { arg "--name $name" - # Disable some security settings to make it possible to - # mount host directories without problems. + # Disable some security settings so host directories can + # be mounted without problems. arg "--security-opt label=disable" # disable labeling so mounts don't need to be labeled. arg "--userns=keep-id" # required for ~/.ssh which is usually 700. + # Configure options to get host-spawn to work inside the + # container. + [ -e "/run/user/$UID/bus" ] && arg "-v /run/user/$UID/bus:/tmp/bus" # Use host dbus. + arg "-e HOST_HOME=$HOME" # Used to translate container path to host. + # Use host networking. arg "--net=host" - # Configure options for host-spawn - arg "-v /run/user/1000/bus:/tmp/bus" # Use host dbus. - arg "-e HOST_HOME=$HOME" # Pas in host $HOME path. - # Mount the wayland socket. Required to get the system # clipbard (wl-copy) working. [ -e "/run/user/$UID/wayland-0" ] && arg "-v /run/user/$UID/wayland-0:/run/user/1000/wayland-0" - # Add a volume for the home directory so it survives - # container upgrades. - arg "-v $name:/home/user:copy" - # Mount the ssh socket, directory and the git config # directory. This gets the host ssh and git configuration # working inside the container. @@ -40,41 +38,48 @@ run_args() { [ -d "$HOME/.ssh" ] && arg "-v $HOME/.ssh:/home/user/.ssh" [ -d "$HOME/.config/git" ] && arg "-v $HOME/.config/git:/home/user/.config/git" - # Mount host directories with programming projects. - [ -d "$HOME/Code" ] && arg "-v $HOME/Code:/home/user/Code" - [ -d "$HOME/Documents" ] && arg "-v $HOME/Documents:/home/user/Documents" - [ -d "$HOME/.config/devcontainer" ] && arg "-v $HOME/.config/devcontainer:/home/user/.config/devcontainer" + # Add a volume for the home directory so it survives + # container updates. + arg "-v $name:/home/user:copy" + + # Add custom user configuration. + config_file="./containers/$name/config.sh" + [ -f "${config_file}" ] && source "${config_file}" } ### MAIN ### -name="devcontainer" -image="ghcr.io/job79/devcontainer:main" -force=false +cd "$(dirname "$(realpath "$0")")" +name=$(<"./state/last-name") +registry=$(<"./state/registry") +pull=false while test $# -gt 0; do case "$1" in - -i) shift && force=true && image="$1" ;; - -f) force=true ;; + -p) pull=true ;; -*) log "unknown argument '$1'" 'x' 31 ;; - *) name="$1" ;; + *) + name="$1" + echo "$1" >"./state/last-name" + ;; esac shift done -if [ "$force" = true ] || [ "$(podman container inspect "$name" -f {{.State.Running}} 2>&1)" != 'true' ]; then +if [ "$pull" = true ] || [ "$(podman container inspect "$name" -f {{.State.Running}} 2>&1)" != 'true' ]; then log "fetching devcontainer updates..." - if [ "$force" = true ] || [ "$(podman container inspect "$name" -f {{.Image}} 2>&1)" != "$(podman pull -q "$image" 2>&1)" ]; then + if [ "$pull" = true ] || [ "$(podman container inspect "$name" -f {{.Image}} 2>&1)" != "$(podman pull -q "$registry/$name" 2>&1)" ]; then if [ $? -eq 0 ]; then log "container image downloaded" '✓' 32 else log "failed to download container image" 'x' 31 fi podman container rm -f -t 1 "$name" 1>/dev/null - podman run -td $(run_args) "$image" + run_args + podman run -td $(run_args) "$registry/$name" else log "no updates available" '✓' 32 fi fi podman start "$name" 1>/dev/null -podman exec -e ENTER_DIR="${PWD/#$HOME/\~}" --detach-keys "ctrl-@" -it "$name" bash -l +podman exec -e CONTAINER_NAME="$name" -e ENTER_DIR="${PWD/#$HOME/\~}" --detach-keys "ctrl-@" -it "$name" bash -l diff --git a/state/last-name b/state/last-name new file mode 100644 index 0000000..4023f20 --- /dev/null +++ b/state/last-name @@ -0,0 +1 @@ +go diff --git a/state/registry b/state/registry new file mode 100644 index 0000000..55df947 --- /dev/null +++ b/state/registry @@ -0,0 +1 @@ +ghcr.io/job79/