diff --git a/plugins/containerenv/README.md b/plugins/containerenv/README.md new file mode 100644 index 000000000..d7928a92e --- /dev/null +++ b/plugins/containerenv/README.md @@ -0,0 +1,82 @@ +# containerenv plugin + +A lightweight plugin that provides convenient functions to access container environment variables from `/run/.containerenv`. Useful in containerized environments (Podman, Docker, Toolbox, etc.). + +To use it, add `containerenv` to the plugins array in your `.zshrc` file: + +```zsh +plugins=(... containerenv) +``` + +## Usage + +### Accessor functions + +Each function reads one key from `/run/.containerenv` and prints its value to stdout. On error (not in a container or missing key), a message is printed to stderr and the function returns 1. + +| Function | Key | Description | +|----------|-----|-------------| +| `containerenv_engine` | `engine` | Container runtime (e.g. `podman`, `docker`) | +| `containerenv_name` | `name` | Container name | +| `containerenv_id` | `id` | Container ID | +| `containerenv_image` | `image` | Image name/reference | +| `containerenv_imageid` | `imageid` | Image ID | +| `containerenv_rootless` | `rootless` | Whether the container is rootless | +| `containerenv_graphrootmounted` | `graphRootMounted` | Whether the graph root is mounted | + +**Examples:** + +```bash +# Show container name +containerenv_name + +# Use in a conditional or variable +if name=$(containerenv_name 2>/dev/null); then + echo "Container: $name" +fi +``` + +### Show all container env vars + +```bash +containerenv_all +``` + +Prints the full contents of `/run/.containerenv`. Exits with 1 if not in a container. + +### Check if running in a container + +```bash +is_containerized +``` + +Returns 0 if `/run/.containerenv` exists, 1 otherwise. Useful in scripts: + +```bash +if is_containerized; then + echo "Inside container: $(containerenv_name 2>/dev/null)" +fi +``` + +### Prompt integration + +Use `containerenv_prompt_info` in your theme to show container info in the prompt (e.g. `📦 container-name`). If not in a container, it prints nothing. When icons are enabled, the prompt shows an engine-specific icon (🐳 docker, ⬢ podman, 📦 other) and optionally 🔓 for rootless containers. + +In a custom theme or in `PROMPT`/`RPROMPT`: + +```zsh +# Example: add to RPROMPT +RPROMPT='$(containerenv_prompt_info)' +``` + +**Environment variable** + +| Variable | Description | +|----------|-------------| +| `OMZ_CONTAINERENV_PROMPT_NO_ICONS` | Set to any value (e.g. `1`) to disable prompt icons. Only the container name is shown (no engine or rootless icons). When unset, icons are shown. | + +--- + +## About `/run/.containerenv` + +Podman (and compatible runtimes) write a file at `/run/.containerenv` inside the container with key=value pairs such as `engine`, `name`, `id`, `image`, `imageid`, `rootless`, and `graphRootMounted`. This plugin reads that file; outside a container or if the file is missing, the accessors report an error. diff --git a/plugins/containerenv/containerenv.plugin.zsh b/plugins/containerenv/containerenv.plugin.zsh new file mode 100644 index 000000000..03e06ed3f --- /dev/null +++ b/plugins/containerenv/containerenv.plugin.zsh @@ -0,0 +1,104 @@ +# Container Environment Plugin for Oh-My-Zsh +# Provides functions to access container environment variables from /run/.containerenv +# Usage: containerenv_engine, containerenv_name, containerenv_id, etc. + +# Check if we're in a container and the file exists +_containerenv_file="/run/.containerenv" + +# Function to read a specific key from the containerenv file +_containerenv_get() { + local key="$1" + + if [[ ! -f "$_containerenv_file" ]]; then + echo "Error: Not running in a container or $_containerenv_file not found" >&2 + return 1 + fi + + local value=$(grep "^${key}=" "$_containerenv_file" | cut -d'=' -f2-) + + if [[ -z "$value" ]]; then + echo "Error: Key '$key' not found in $_containerenv_file" >&2 + return 1 + fi + + # Strip surrounding double quotes if present (e.g. name="container-name" in file) + value="${value#\"}" + value="${value%\"}" + + echo "$value" +} + +# Individual accessor functions +containerenv_engine() { + _containerenv_get "engine" +} + +containerenv_name() { + _containerenv_get "name" +} + +containerenv_id() { + _containerenv_get "id" +} + +containerenv_image() { + _containerenv_get "image" +} + +containerenv_imageid() { + _containerenv_get "imageid" +} + +containerenv_rootless() { + local raw ret + raw="$(_containerenv_get "rootless" 2>/dev/null)" + ret=$? + if [[ $ret -ne 0 || -z "$raw" ]]; then + echo "false" + return 0 + fi + case "${(L)raw}" in + (1|true|yes) echo "true" ;; + (*) echo "false" ;; + esac +} + +containerenv_graphrootmounted() { + _containerenv_get "graphRootMounted" +} + +# Function to display all container environment variables +containerenv_all() { + if [[ ! -f "$_containerenv_file" ]]; then + echo "Error: Not running in a container or $_containerenv_file not found" >&2 + return 1 + fi + + cat "$_containerenv_file" +} + +# Function to check if running in a container +is_containerized() { + [[ -f "$_containerenv_file" ]] +} + +# Optional: Add a prompt segment function for use with oh-my-zsh themes +# Icon for the prompt: 🐳 docker, ⬢ podman, 📦 other/default +# Set OMZ_CONTAINERENV_PROMPT_NO_ICONS to disable prompt icons (show container name only) +containerenv_prompt_info() { + if is_containerized; then + local container_name=$(containerenv_name 2>/dev/null) + if [[ -n "$container_name" ]]; then + local icons="" + if [[ -z "${OMZ_CONTAINERENV_PROMPT_NO_ICONS:-}" ]]; then + icons="📦" + case "${(L)$(containerenv_engine 2>/dev/null)}" in + (docker*) icons="🐳" ;; + (podman*) icons="⬢" ;; + esac + [[ "$(containerenv_rootless 2>/dev/null)" == "true" ]] && icons="${icons} 🔓" + fi + echo "${icons:+$icons }${container_name}" + fi + fi +}