From 2899ee23ebbd677a74972129f3cc29d58fc8369d Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Fri, 11 Apr 2025 22:09:04 -0500 Subject: [PATCH] its working! --- .gitignore | 1 + krayt/bundles.py | 139 ++++++++--------- krayt/cli/__init__.py | 3 +- krayt/cli/pod.py | 37 +---- krayt/cli/templates.py | 17 +-- krayt/package.py | 152 ++++++++++++------- krayt/templates.py | 2 + krayt/templates/install.sh | 109 ++++++++------ test.sh | 254 +++++++++++++++++++++++++++---- test.yaml | 300 +++++++++++++++++++++++++------------ 10 files changed, 680 insertions(+), 334 deletions(-) diff --git a/.gitignore b/.gitignore index e1a3186..6f4e31a 100644 --- a/.gitignore +++ b/.gitignore @@ -962,3 +962,4 @@ FodyWeavers.xsd # Additional files built by Visual Studio # End of https://www.toptal.com/developers/gitignore/api/vim,node,data,emacs,python,pycharm,executable,sublimetext,visualstudio,visualstudiocode +*.null-ls* diff --git a/krayt/bundles.py b/krayt/bundles.py index a375140..cecc8d9 100644 --- a/krayt/bundles.py +++ b/krayt/bundles.py @@ -10,78 +10,79 @@ basics = [ "bash", "coreutils", ] -pretty = [ - *basics, - "starship", - "atuin", - "bash", - "zsh", - "fish", - "bat", - "eza", -] -networking = [ - *basics, - "mtr", - "bind-tools", - "aws-cli", - "curl", - "wget", - "iperf3", - "nmap", - "traceroute", - "netcat-openbsd", -] +bundles = { + "basics": [ + *basics, + ], + "pretty": [ + *basics, + "starship", + "atuin", + "bash", + "zsh", + "fish", + "bat", + "eza", + ], + "networking": [ + *basics, + "mtr", + "bind-tools", + "aws-cli", + "curl", + "wget", + "iperf3", + "nmap", + "traceroute", + "netcat-openbsd", + ], + "database": [ + *basics, + "sqlite", + "sqlite-dev", + "sqlite-libs", + "postgresql", + "mysql", + "mariadb", + "redis", + "mongodb", + ], + "storage": [ + *basics, + "ncdu", + "dust", + "file", + "hexyl", + "ripgrep", + "fd", + "fzf", + "difftastic", + ], + "search": [ + *basics, + "ripgrep", + "fd", + "fzf", + "difftastic", + ], + "monitoring": [ + *basics, + "htop", + "bottom", + "mtr", + ], +} -database = [ - *basics, - "sqlite", - "sqlite-dev", - "sqlite-libs", - "postgresql", - "mysql", - "mariadb", - "redis", - "mongodb", -] - -storage = [ - *basics, - "ncdu", - "dust", - "file", - "hexyl", - "ripgrep", - "fd", - "fzf", - "difftastic", -] - -search = [ - *basics, - "ripgrep", - "fd", - "fzf", - "difftastic", -] - -monitoring = [ - *basics, - "htop", - "bottom", - "mtr", -] - -all = list( +bundles["all"] = list( set( [ - *basics, - *pretty, - *networking, - *database, - *storage, - *search, - *monitoring, + *bundles["basics"], + *bundles["pretty"], + *bundles["networking"], + *bundles["database"], + *bundles["storage"], + *bundles["search"], + *bundles["monitoring"], ] ) ) diff --git a/krayt/cli/__init__.py b/krayt/cli/__init__.py index 06e5c40..d5c6f0c 100644 --- a/krayt/cli/__init__.py +++ b/krayt/cli/__init__.py @@ -1,6 +1,6 @@ from krayt import __version__ from krayt.cli.bundles import app as bundles_app -from krayt.cli.pod import app as pod_app, create, exec, logs +from krayt.cli.pod import app as pod_app, create, exec, logs, clean from krayt.cli.templates import app as templates_app from typer import Typer @@ -10,6 +10,7 @@ app.add_typer(templates_app, name="templates", no_args_is_help=True) app.add_typer(pod_app, name="pod", no_args_is_help=True) app.command(name="create")(create) app.command(name="c")(create) +app.command(name="clean")(clean) app.command(name="exec")(exec) app.command(name="logs")(logs) app.add_typer(bundles_app, name="bundles", no_args_is_help=True) diff --git a/krayt/cli/pod.py b/krayt/cli/pod.py index 93a9a80..8190073 100644 --- a/krayt/cli/pod.py +++ b/krayt/cli/pod.py @@ -296,31 +296,6 @@ def create_inspector_job( template_name = "base.sh" template = env.get_template(template_name) - additional_packages = [ - "ripgrep", - "exa", - "ncdu", - "dust", - "file", - "hexyl", - "jq", - "yq", - "bat", - "fd", - "fzf", - "htop", - "bottom", - "difftastic", - "mtr", - "bind-tools", - "aws-cli", - "sqlite", - "sqlite-dev", - "sqlite-libs", - "bash", - "neovim", - "starship", - ] pvcs = None pre_init_scripts = None post_init_scripts = None @@ -631,8 +606,6 @@ def create( # For create, we want to list all pods, not just Krayt pods selected_namespace = None selected_pod = None - typer.echo(namespace) - typer.echo(clone) if namespace is None and clone is not None and "/" in clone: selected_namespace, selected_pod = clone.split("/", 1) @@ -656,9 +629,8 @@ def create( typer.echo("No pod selected.") raise typer.Exit(1) - typer.echo(f"Selected pod exists: {selected_pod in (p[0] for p in pods)}") - typer.echo(f"Selected pod: {selected_pod} ({selected_namespace})") - raise typer.Exit(1) + # typer.echo(f"Selected pod exists: {selected_pod in (p[0] for p in pods)}") + # typer.echo(f"Selected pod: {selected_pod} ({selected_namespace})") pod_spec = get_pod_spec(selected_pod, selected_namespace) volume_mounts, volumes = get_pod_volumes_and_mounts(pod_spec) @@ -671,6 +643,11 @@ def create( volumes, image=image, imagepullsecret=imagepullsecret, + additional_packages=additional_packages, + pre_init_scripts=pre_init_scripts, + post_init_scripts=post_init_scripts, + pre_init_hooks=pre_init_hooks, + post_init_hooks=post_init_hooks, ) # Output the job manifest diff --git a/krayt/cli/templates.py b/krayt/cli/templates.py index 04a1843..5a0c361 100644 --- a/krayt/cli/templates.py +++ b/krayt/cli/templates.py @@ -2,18 +2,7 @@ from krayt.templates import env import typer from typing import List, Optional -# app = typer.Typer() -app = typer.Typer( - context_settings={ - "auto_envvar_prefix": "KRAYT", - "help_option_names": ["-h", "--help"], - "show_default": True, - "allow_interspersed_args": True, - "ignore_unknown_options": False, - "max_content_width": None, - "suggest_command": True, - } -) +app = typer.Typer() @app.command() @@ -103,6 +92,8 @@ def motd( template_name = "motd.sh" template = env.get_template(template_name) rendered = template.render( - volumes=volumes, pvcs=pvcs, additional_packages=additional_packages + volumes=volumes, + pvcs=pvcs, + additional_packages=additional_packages, ) print(rendered) diff --git a/krayt/package.py b/krayt/package.py index 2e78ab1..907a412 100644 --- a/krayt/package.py +++ b/krayt/package.py @@ -1,7 +1,7 @@ +from krayt.bundles import bundles from more_itertools import unique_everseen -from pydantic import BaseModel, BeforeValidator, model_validator -from typing import Annotated, List, Literal, Optional -from typing_extensions import Self +from pydantic import BaseModel, BeforeValidator +from typing import Annotated, List, Literal, Optional, Union SUPPORTED_KINDS = { @@ -16,6 +16,26 @@ SUPPORTED_KINDS = { "npm", "go", "gh", + "group", + "bundle", +} + +DEPENDENCIES = { + "uv": [ + "curl", + "curlsh:https://astral.sh/uv/install.sh", + ], + "installer": [ + "curl", + ], + "i": ["curl"], + "curlbash": ["curl"], + "curlsh": ["curl"], + "cargo": ["cargo"], + "pipx": ["pipx"], + "npm": ["npm"], + "go": ["go"], + "gh": ["gh"], } @@ -34,22 +54,11 @@ class Package(BaseModel): """ kind: Annotated[ - Literal[ - "system", - "uv", - "i", - "curlsh", - "curlbash", - "cargo", - "pipx", - "npm", - "go", - "gh", - ], + Literal[*SUPPORTED_KINDS], BeforeValidator(validate_kind), ] = "system" value: str - dependencies: Optional[List["Package"]] = None + # dependencies: Optional[List["Package"]] = None pre_install_hook: Optional[str] = None post_install_hook: Optional[str] = None @@ -64,26 +73,29 @@ class Package(BaseModel): else: return cls(kind="system", value=raw.strip()) - @model_validator(mode="after") - def validate_dependencies(self) -> Self: - if self.dependencies: - return self - dependencies = [] - - if self.kind in ["uv", "i", "installer", "curlbash", "curlsh", "gh"]: - dependencies.append(Package.from_raw("curl")) - if self.kind == "cargo": - dependencies.append(Package.from_raw("cargo")) - if self.kind == "pipx": - dependencies.append(Package.from_raw("pipx")) - if self.kind == "npm": - dependencies.append(Package.from_raw("npm")) - if self.kind == "go": - dependencies.append(Package.from_raw("go")) - - self.dependencies = dependencies - return self - + # @model_validator(mode="after") + # def validate_dependencies(self) -> Self: + # if self.dependencies: + # return self + # dependencies = [] + # + # if self.kind in ["uv", "i", "installer", "curlbash", "curlsh", "gh"]: + # dependencies.append(Package.from_raw("curl")) + # dependencies.append( + # Package.from_raw("curlsh:https://astral.sh/uv/install.sh") + # ) + # if self.kind == "cargo": + # dependencies.append(Package.from_raw("cargo")) + # if self.kind == "pipx": + # dependencies.append(Package.from_raw("pipx")) + # if self.kind == "npm": + # dependencies.append(Package.from_raw("npm")) + # if self.kind == "go": + # dependencies.append(Package.from_raw("go")) + # + # self.dependencies = dependencies + # return self + # def is_system(self) -> bool: return self.kind == "system" @@ -92,12 +104,14 @@ class Package(BaseModel): Generate the bash install command snippet for this package. """ cmd = "" - if self.kind == "system": + if self.kind in ["bundle", "group"]: + cmd = "" + elif self.kind == "system": cmd = f"detect_package_manager_and_install {self.value}" elif self.kind == "uv": cmd = f"uv tool install {self.value}" elif self.kind in ["i", "installer", "gh"]: - cmd = f"curl -fsSL https://i.jpillora.com/{self.value} | sh" + cmd = f"installer {self.value}" elif self.kind == "curlsh": cmd = f"curl -fsSL {self.value} | sh" elif self.kind == "curlbash": @@ -120,28 +134,58 @@ class Package(BaseModel): return cmd -if __name__ == "__main__": - raw_inputs = [ - "curl", - "wget", - "uv:copier", - "i:sharkdp/fd", - "curlsh:https://example.com/install.sh", - ] - - packages = [Package.from_raw(raw) for raw in raw_inputs] - dependencies = [] +def get_install_script(packages: Union[str, List[str]]) -> str: + if packages is None: + return [] + if isinstance(packages, str): + packages = [packages] + bundled_packages = [] for package in packages: - if package.dependencies: - dependencies.extend( - [dependency.install_command() for dependency in package.dependencies] - ) + if package.startswith("bundle:") or package.startswith("group:"): + _package = package.split(":")[1].strip() + bundled_packages.extend(bundles.get(_package, [])) + packages = list(unique_everseen([*bundled_packages, *packages])) + + packages = [Package.from_raw(raw) for raw in packages] + kinds_used = [package.kind for package in packages] + dependencies = [] + for kind in kinds_used: + dependencies.extend(DEPENDENCIES.get(kind, [])) + dependencies = list( + unique_everseen( + [Package.from_raw(raw).install_command() for raw in dependencies] + ) + ) + # for package in packages: + # if package.dependencies: + # dependencies.extend( + # [dependency.install_command() for dependency in package.dependencies] + # ) installs = [package.install_command() for package in packages] post_hooks = [] for package in packages: if package.post_install_hook: post_hooks.append(package.post_install_hook.strip()) + pre_hooks = [] + for package in packages: + if package.pre_install_hook: + pre_hooks.append(package.pre_install_hook.strip()) # Final full script - full_script = list(unique_everseen([*dependencies, *installs, *post_hooks])) + full_script = list( + unique_everseen([*pre_hooks, *dependencies, *installs, *post_hooks]) + ) + return "\n".join(full_script) if full_script else full_script + + +if __name__ == "__main__": + raw_inputs = [ + "bundle:storage", + "wget", + "uv:copier", + "i:sharkdp/fd", + "curlsh:https://example.com/install.sh", + ] + full_script = get_install_script(raw_inputs) + print("\n".join(full_script)) diff --git a/krayt/templates.py b/krayt/templates.py index 53d902f..7b3ba95 100644 --- a/krayt/templates.py +++ b/krayt/templates.py @@ -1,4 +1,5 @@ from jinja2 import Environment, FileSystemLoader +from krayt.package import get_install_script from pathlib import Path # Get the two template directories @@ -9,3 +10,4 @@ template_dirs = [ # Create the Jinja environment env = Environment(loader=FileSystemLoader([str(path) for path in template_dirs])) +env.globals["get_install_script"] = get_install_script diff --git a/krayt/templates/install.sh b/krayt/templates/install.sh index 8e0c8d9..de056ad 100644 --- a/krayt/templates/install.sh +++ b/krayt/templates/install.sh @@ -1,65 +1,88 @@ {% if additional_packages %} +# Detect package manager +if command -v apt >/dev/null 2>&1; then + PKG_MANAGER="apt" + UPDATE_CMD="apt update" + INSTALL_CMD="apt install -y" +elif command -v dnf >/dev/null 2>&1; then + PKG_MANAGER="dnf" + UPDATE_CMD="" + INSTALL_CMD="dnf install -y" +elif command -v yum >/dev/null 2>&1; then + PKG_MANAGER="yum" + UPDATE_CMD="" + INSTALL_CMD="yum install -y" +elif command -v pacman >/dev/null 2>&1; then + PKG_MANAGER="pacman" + UPDATE_CMD="" + INSTALL_CMD="pacman -Sy --noconfirm" +elif command -v zypper >/dev/null 2>&1; then + PKG_MANAGER="zypper" + UPDATE_CMD="" + INSTALL_CMD="zypper install -y" +elif command -v apk >/dev/null 2>&1; then + PKG_MANAGER="apk" + UPDATE_CMD="" + INSTALL_CMD="apk add" +else + echo "No supported package manager found." + exit 2 +fi + +echo "Using package manager: $PKG_MANAGER" + +# Run update once if needed +if [ -n "$UPDATE_CMD" ]; then + echo "Running package manager update..." + eval "$UPDATE_CMD" +fi + detect_package_manager_and_install() { if [ $# -eq 0 ]; then echo "Usage: detect_package_manager_and_install [package2] [...]" return 1 fi - if command -v apt >/dev/null 2>&1; then - PKG_MANAGER="apt" - UPDATE_CMD="apt update &&" - INSTALL_CMD="apt install -y" - elif command -v dnf >/dev/null 2>&1; then - PKG_MANAGER="dnf" - UPDATE_CMD="" - INSTALL_CMD="dnf install -y" - elif command -v yum >/dev/null 2>&1; then - PKG_MANAGER="yum" - UPDATE_CMD="" - INSTALL_CMD="yum install -y" - elif command -v pacman >/dev/null 2>&1; then - PKG_MANAGER="pacman" - UPDATE_CMD="" - INSTALL_CMD="pacman -Sy --noconfirm" - elif command -v zypper >/dev/null 2>&1; then - PKG_MANAGER="zypper" - UPDATE_CMD="" - INSTALL_CMD="zypper install -y" - elif command -v apk >/dev/null 2>&1; then - PKG_MANAGER="apk" - UPDATE_CMD="" - INSTALL_CMD="apk add" - else - echo "No supported package manager found." - return 2 - fi - - echo "Using package manager: $PKG_MANAGER" - - if [ -n "$UPDATE_CMD" ]; then - echo "Running package manager update..." - eval "$UPDATE_CMD" - fi - - FAILED_PKGS=() + FAILED_PKGS="" for pkg in "$@"; do echo "Installing package: $pkg" - if ! eval "$INSTALL_CMD $pkg"; then + if ! $INSTALL_CMD $pkg; then echo "⚠️ Warning: Failed to install package: $pkg" - FAILED_PKGS+=("$pkg") + FAILED_PKGS="$FAILED_PKGS $pkg" fi done - - if [ ${#FAILED_PKGS[@]} -ne 0 ]; then + {% raw %} + if [ -n "$FAILED_PKGS" ]; then echo "⚠️ The following packages failed to install:" - for failed_pkg in "${FAILED_PKGS[@]}"; do + for failed_pkg in $FAILED_PKGS; do echo " - $failed_pkg" done else echo "✅ All requested packages installed successfully." fi + {% endraw %} } -detect_package_manager_and_install {% for package in additional_packages %}{{ package | trim }}{% if not loop.last %} {% endif %}{% endfor %} +installer() { + if [ $# -eq 0 ]; then + echo "Usage: installer [package2] [...]" + return 1 + fi + + for pkg in "$@"; do + echo "Installing package with installer: $pkg" + ( + orig_dir="$(pwd)" + cd /usr/local/bin || exit 1 + curl -fsSL https://i.jpillora.com/${pkg} | sh + cd "$orig_dir" || exit 1 + ) + done +} {% endif %} + +{% if additional_packages %} +{{ get_install_script(additional_packages) | safe }} +{% endif %} + diff --git a/test.sh b/test.sh index 117fb41..1643cab 100644 --- a/test.sh +++ b/test.sh @@ -1,51 +1,247 @@ -detect_package_manager_and_install_command() { - # Accept packages as arguments - PACKAGES=("$@") - - if [[ ${#PACKAGES[@]} -eq 0 ]]; then - echo "Usage: detect_package_manager_and_install_command [package2] [...]" +mkdir -p /etc/krayt +cat <<'KRAYT_INIT_SH_EOF' >/etc/krayt/init.sh +detect_package_manager_and_install() { + if [ $# -eq 0 ]; then + echo "Usage: detect_package_manager_and_install [package2] [...]" return 1 fi - if command -v apt &>/dev/null; then + if command -v apt >/dev/null 2>&1; then PKG_MANAGER="apt" - UPDATE_CMD="sudo apt update" - INSTALL_CMD="sudo apt install -y" - elif command -v dnf &>/dev/null; then + UPDATE_CMD="apt update &&" + INSTALL_CMD="apt install -y" + elif command -v dnf >/dev/null 2>&1; then PKG_MANAGER="dnf" UPDATE_CMD="" - INSTALL_CMD="sudo dnf install -y" - elif command -v yum &>/dev/null; then + INSTALL_CMD="dnf install -y" + elif command -v yum >/dev/null 2>&1; then PKG_MANAGER="yum" UPDATE_CMD="" - INSTALL_CMD="sudo yum install -y" - elif command -v pacman &>/dev/null; then + INSTALL_CMD="yum install -y" + elif command -v pacman >/dev/null 2>&1; then PKG_MANAGER="pacman" UPDATE_CMD="" - INSTALL_CMD="sudo pacman -Sy --noconfirm" - elif command -v zypper &>/dev/null; then + INSTALL_CMD="pacman -Sy --noconfirm" + elif command -v zypper >/dev/null 2>&1; then PKG_MANAGER="zypper" UPDATE_CMD="" - INSTALL_CMD="sudo zypper install -y" - elif command -v apk &>/dev/null; then + INSTALL_CMD="zypper install -y" + elif command -v apk >/dev/null 2>&1; then PKG_MANAGER="apk" UPDATE_CMD="" - INSTALL_CMD="sudo apk add" + INSTALL_CMD="apk add" else echo "No supported package manager found." return 2 fi - # Build the full install command - if [[ -n "$UPDATE_CMD" ]]; then - # echo $UPDATE_CMD - # $UPDATE_CMD - echo $INSTALL_CMD ${PACKAGES[*]} - $INSTALL_CMD ${PACKAGES[*]} - else - echo $INSTALL_CMD ${PACKAGES[*]} - $INSTALL_CMD ${PACKAGES[*]} + echo "Using package manager: $PKG_MANAGER" + + if [ -n "$UPDATE_CMD" ]; then + echo "Running package manager update..." + eval "$UPDATE_CMD" fi + + FAILED_PKGS="" + + for pkg in "$@"; do + echo "Installing package: $pkg" + if ! eval "$INSTALL_CMD $pkg"; then + echo "⚠️ Warning: Failed to install package: $pkg" + FAILED_PKGS="$FAILED_PKGS $pkg" + fi + done + + if [ -n "$FAILED_PKGS" ]; then + echo "⚠️ The following packages failed to install:" + for failed_pkg in $FAILED_PKGS; do + echo " - $failed_pkg" + done + else + echo "✅ All requested packages installed successfully." + fi + } -detect_package_manager_and_install_command git htop +installer() { + if [ $# -eq 0 ]; then + echo "Usage: installer [package2] [...]" + return 1 + fi + + for pkg in "$@"; do + echo "Installing package with installer: $pkg" + ( + orig_dir="$(pwd)" + cd /usr/local/bin || exit 1 + curl -fsSL https://i.jpillora.com/${pkg} | sh + cd "$orig_dir" || exit 1 + ) + done +} + + + +detect_package_manager_and_install eza +detect_package_manager_and_install hexyl +detect_package_manager_and_install mariadb +detect_package_manager_and_install coreutils +detect_package_manager_and_install ncdu +detect_package_manager_and_install postgresql +detect_package_manager_and_install atuin +detect_package_manager_and_install redis +detect_package_manager_and_install file +detect_package_manager_and_install netcat-openbsd +detect_package_manager_and_install traceroute +detect_package_manager_and_install fd +detect_package_manager_and_install iperf3 +detect_package_manager_and_install aws-cli +detect_package_manager_and_install dust +detect_package_manager_and_install sqlite-dev +detect_package_manager_and_install fish +detect_package_manager_and_install bat +detect_package_manager_and_install ripgrep +detect_package_manager_and_install difftastic +detect_package_manager_and_install zsh +detect_package_manager_and_install sqlite-libs +detect_package_manager_and_install bind-tools +detect_package_manager_and_install nmap +detect_package_manager_and_install mysql +detect_package_manager_and_install htop +detect_package_manager_and_install sqlite +detect_package_manager_and_install fzf +detect_package_manager_and_install bottom +detect_package_manager_and_install wget +detect_package_manager_and_install mtr +detect_package_manager_and_install bash +detect_package_manager_and_install curl +detect_package_manager_and_install starship +detect_package_manager_and_install mongodb +detect_package_manager_and_install jq +detect_package_manager_and_install yq + + + +cat </etc/motd +┌───────────────────────────────────┐ +│Krayt Dragon's Lair │ +│A safe haven for volume inspection │ +└───────────────────────────────────┘ + +"Inside every volume lies a pearl of wisdom waiting to be discovered." + +Additional Packages: +- bundle:all + +EOF +KRAYT_MARKER_START="# >>> Added by krayt-inject <<<" +KRAYT_MARKER_END='# <<< End krayt-inject >>>' +KRAYT_BLOCK=' +if [ -t 1 ] && [ -f /etc/motd ] && [ -z "$MOTD_SHOWN" ]; then + cat /etc/motd + export MOTD_SHOWN=1 +fi + +# fix $SHELL, not set in some distros like alpine +if [ -n "$BASH_VERSION" ]; then + export SHELL=/bin/bash +elif [ -n "$ZSH_VERSION" ]; then + export SHELL=/bin/zsh +else + export SHELL=/bin/sh +fi + +# krayt ENVIRONMENT +export KRAYT_ADDITIONAL_PACKAGES="bundle:all" +# Universal shell initializers + +# Prompt +if command -v starship >/dev/null 2>&1; then + eval "$(starship init "$(basename "$SHELL")")" +fi + +# Smarter cd +if command -v zoxide >/dev/null 2>&1; then + eval "$(zoxide init "$(basename "$SHELL")")" +fi + +# Smarter shell history +if command -v atuin >/dev/null 2>&1; then + eval "$(atuin init "$(basename "$SHELL")")" +fi + +if command -v mcfly >/dev/null 2>&1; then + eval "$(mcfly init "$(basename "$SHELL")")" +fi + +# Directory-based environment +if command -v direnv >/dev/null 2>&1; then + eval "$(direnv hook "$(basename "$SHELL")")" +fi + +if command -v fzf >/dev/null 2>&1; then + case "$(basename "$SHELL")" in + bash|zsh|fish) + eval "$(fzf --$(basename "$SHELL"))" + ;; + *) + # shell not supported for fzf init + ;; + esac +fi +# "Did you mean...?" for mistyped commands +if command -v thefuck >/dev/null 2>&1; then + eval "$(thefuck --alias)" +fi +' +cat </etc/.kraytrc +$KRAYT_MARKER_START +$KRAYT_BLOCK +$KRAYT_MARKER_END +EOF + +KRAYT_RC_SOURCE=' +if [ -f /etc/.kraytrc ]; then + . /etc/.kraytrc +fi +' + +# List of common rc/profile files to patch +RC_FILES=" +/etc/profile +/etc/bash.bashrc +/etc/bash/bashrc +/etc/bashrc +/etc/ashrc +/etc/zsh/zshrc +/etc/zsh/zprofile +/etc/shinit +/etc/fish/config.fish +" + +echo "Searching for rc files..." + +for rc_file in $RC_FILES; do + if [ -f "$rc_file" ]; then + echo "* Found $rc_file" + + # Check if already patched + if grep -q "$KRAYT_MARKER_START" "$rc_file"; then + echo "- $rc_file already has krayt block. Skipping." + else + echo "+ Patching $rc_file" + echo "" >>"$rc_file" + echo "$KRAYT_MARKER_START" >>"$rc_file" + echo "$KRAYT_RC_SOURCE" >>"$rc_file" + echo "$KRAYT_MARKER_END" >>"$rc_file" + fi + fi +done +echo "Krayt environment ready. Sleeping forever..." +trap "echo 'Received SIGTERM. Exiting...'; exit 0" TERM +tail -f /dev/null & +wait +KRAYT_INIT_SH_EOF + +chmod +x /etc/krayt/init.sh +/etc/krayt/init.sh diff --git a/test.yaml b/test.yaml index 194d69b..b2b19a0 100644 --- a/test.yaml +++ b/test.yaml @@ -1,96 +1,206 @@ -apiVersion: batch/v1 -kind: Job -metadata: - name: htmx-patterns-66bfd987d7-98sw7-krayt-1744164311 - namespace: htmx-patterns - labels: - app: krayt - annotations: - pvcs: none -spec: - template: - metadata: - labels: - app: krayt - spec: - containers: - - name: inspector - image: alpine:latest - command: - - sh - - -c - - "mkdir -p /etc/krayt\ncat <<'KRAYT_INIT_SH_EOF' >/etc/krayt/init.sh\ndetect_package_manager_and_install_command()\ - \ {\n\tif [ $# -eq 0 ]; then\n\t\techo \"Usage: detect_package_manager_and_install_command\ - \ [package2] [...]\"\n\t\treturn 1\n\tfi\n\n\tif command -v apt\ - \ >/dev/null 2>&1; then\n\t\tPKG_MANAGER=\"apt\"\n\t\tUPDATE_CMD=\"apt update\ - \ &&\"\n\t\tINSTALL_CMD=\"apt install -y\"\n\telif command -v dnf >/dev/null\ - \ 2>&1; then\n\t\tPKG_MANAGER=\"dnf\"\n\t\tUPDATE_CMD=\"\"\n\t\tINSTALL_CMD=\"\ - dnf install -y\"\n\telif command -v yum >/dev/null 2>&1; then\n\t\tPKG_MANAGER=\"\ - yum\"\n\t\tUPDATE_CMD=\"\"\n\t\tINSTALL_CMD=\"yum install -y\"\n\telif command\ - \ -v pacman >/dev/null 2>&1; then\n\t\tPKG_MANAGER=\"pacman\"\n\t\tUPDATE_CMD=\"\ - \"\n\t\tINSTALL_CMD=\"pacman -Sy --noconfirm\"\n\telif command -v zypper\ - \ >/dev/null 2>&1; then\n\t\tPKG_MANAGER=\"zypper\"\n\t\tUPDATE_CMD=\"\"\ - \n\t\tINSTALL_CMD=\"zypper install -y\"\n\telif command -v apk >/dev/null\ - \ 2>&1; then\n\t\tPKG_MANAGER=\"apk\"\n\t\tUPDATE_CMD=\"\"\n\t\tINSTALL_CMD=\"\ - apk add\"\n\telse\n\t\techo \"No supported package manager found.\"\n\t\t\ - return 2\n\tfi\n\n\tPACKAGES=\"$*\"\n\n\tif [ -n \"$UPDATE_CMD\" ]; then\n\ - \t\techo \"$UPDATE_CMD\n echo $INSTALL_CMD $PACKAGES\"\n\t\t$UPDATE_CMD\n\ - \t\t$INSTALL_CMD $PACKAGES\n\n\telse\n\t\techo \"$INSTALL_CMD $PACKAGES\"\ - \n\t\t$INSTALL_CMD $PACKAGES\n\tfi\n}\n\ndetect_package_manager_and_install_command\ - \ ripgrep exa ncdu dust file hexyl jq yq bat fd fzf htop bottom difftastic\ - \ mtr bind-tools aws-cli sqlite sqlite-dev sqlite-libs bash neovim starship\n\ - \ncat </etc/motd\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ - \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ - \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ - \u2500\u2500\u2500\u2500\u2510\n\u2502Krayt Dragon's Lair \ - \ \u2502\n\u2502A safe haven for volume inspection \u2502\n\u2514\u2500\ - \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ - \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ - \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\n\"\ - Inside every volume lies a pearl of wisdom waiting to be discovered.\"\n\ - \nAdditional Packages:\n- ripgrep\n- exa\n- ncdu\n- dust\n- file\n- hexyl\n\ - - jq\n- yq\n- bat\n- fd\n- fzf\n- htop\n- bottom\n- difftastic\n- mtr\n\ - - bind-tools\n- aws-cli\n- sqlite\n- sqlite-dev\n- sqlite-libs\n- bash\n\ - - neovim\n- starship\n\nEOF\nKRAYT_MARKER_START=\"# >>> Added by krayt-inject\ - \ <<<\"\nKRAYT_MARKER_END='# <<< End krayt-inject >>>'\nKRAYT_BLOCK='\n\ - if [ -t 1 ] && [ -f /etc/motd ] && [ -z \"$MOTD_SHOWN\" ]; then\n cat\ - \ /etc/motd\n export MOTD_SHOWN=1\nfi\n\n# fix $SHELL, not set in some\ - \ distros like alpine\nif [ -n \"$BASH_VERSION\" ]; then\n export SHELL=/bin/bash\n\ - elif [ -n \"$ZSH_VERSION\" ]; then\n export SHELL=/bin/zsh\nelse\n \ - \ export SHELL=/bin/sh\nfi\n\n# krayt ENVIRONMENT\nexport KRAYT_ADDITIONAL_PACKAGES=\"\ - ripgrep exa ncdu dust file hexyl jq yq bat fd fzf htop bottom difftastic\ - \ mtr bind-tools aws-cli sqlite sqlite-dev sqlite-libs bash neovim starship\"\ - \n# Universal shell initializers\n\n# Prompt\nif command -v starship >/dev/null\ - \ 2>&1; then\n\teval \"$(starship init \"$(basename \"$SHELL\")\")\"\nfi\n\ - \n# Smarter cd\nif command -v zoxide >/dev/null 2>&1; then\n\teval \"$(zoxide\ - \ init \"$(basename \"$SHELL\")\")\"\nfi\n\n# Smarter shell history\nif\ - \ command -v atuin >/dev/null 2>&1; then\n\teval \"$(atuin init \"$(basename\ - \ \"$SHELL\")\")\"\nfi\n\nif command -v mcfly >/dev/null 2>&1; then\n\t\ - eval \"$(mcfly init \"$(basename \"$SHELL\")\")\"\nfi\n\n# Directory-based\ - \ environment\nif command -v direnv >/dev/null 2>&1; then\n\teval \"$(direnv\ - \ hook \"$(basename \"$SHELL\")\")\"\nfi\n\nif command -v fzf >/dev/null\ - \ 2>&1; then\n case \"$(basename \"$SHELL\")\" in\n bash|zsh|fish)\n\ - \ eval \"$(fzf --$(basename \"$SHELL\"))\"\n ;;\n\ - \ *)\n # shell not supported for fzf init\n \ - \ ;;\n esac\nfi\n# \"Did you mean...?\" for mistyped commands\nif command\ - \ -v thefuck >/dev/null 2>&1; then\n\teval \"$(thefuck --alias)\"\nfi\n\ - '\ncat </etc/.kraytrc\n$KRAYT_MARKER_START\n$KRAYT_BLOCK\n$KRAYT_MARKER_END\n\ - EOF\n\nKRAYT_RC_SOURCE='\nif [ -f /etc/.kraytrc ]; then\n . /etc/.kraytrc\n\ - fi\n'\n\n# List of common rc/profile files to patch\nRC_FILES=\"\n/etc/profile\n\ - /etc/bash.bashrc\n/etc/bash/bashrc\n/etc/bashrc\n/etc/ashrc\n/etc/zsh/zshrc\n\ - /etc/zsh/zprofile\n/etc/shinit\n/etc/fish/config.fish\n\"\n\necho \"Searching\ - \ for rc files...\"\n\nfor rc_file in $RC_FILES; do\n\tif [ -f \"$rc_file\"\ - \ ]; then\n\t\techo \"* Found $rc_file\"\n\n\t\t# Check if already patched\n\ - \t\tif grep -q \"$KRAYT_MARKER_START\" \"$rc_file\"; then\n\t\t\techo \"\ - - $rc_file already has krayt block. Skipping.\"\n\t\telse\n\t\t\techo \"\ - + Patching $rc_file\"\n\t\t\techo \"\" >>\"$rc_file\"\n\t\t\techo \"$KRAYT_MARKER_START\"\ - \ >>\"$rc_file\"\n\t\t\techo \"$KRAYT_RC_SOURCE\" >>\"$rc_file\"\n\t\t\t\ - echo \"$KRAYT_MARKER_END\" >>\"$rc_file\"\n\t\tfi\n\tfi\ndone\necho \"Krayt\ - \ environment ready. Sleeping forever...\"\ntrap \"echo 'Received SIGTERM.\ - \ Exiting...'; exit 0\" TERM\ntail -f /dev/null &\nwait\nKRAYT_INIT_SH_EOF\n\ - \nchmod +x /etc/krayt/init.sh\n/etc/krayt/init.sh" - env: [] - volumeMounts: [] - volumes: [] - restartPolicy: Never +mkdir -p /etc/krayt +cat <<'KRAYT_INIT_SH_EOF' >/etc/krayt/init.sh +detect_package_manager_and_install() { + if [ $# -eq 0 ]; then + echo "Usage: detect_package_manager_and_install [package2] [...]" + return 1 + fi + if command -v apt >/dev/null 2>&1; then + PKG_MANAGER="apt" + UPDATE_CMD="apt update &&" + INSTALL_CMD="apt install -y" + elif command -v dnf >/dev/null 2>&1; then + PKG_MANAGER="dnf" + UPDATE_CMD="" + INSTALL_CMD="dnf install -y" + elif command -v yum >/dev/null 2>&1; then + PKG_MANAGER="yum" + UPDATE_CMD="" + INSTALL_CMD="yum install -y" + elif command -v pacman >/dev/null 2>&1; then + PKG_MANAGER="pacman" + UPDATE_CMD="" + INSTALL_CMD="pacman -Sy --noconfirm" + elif command -v zypper >/dev/null 2>&1; then + PKG_MANAGER="zypper" + UPDATE_CMD="" + INSTALL_CMD="zypper install -y" + elif command -v apk >/dev/null 2>&1; then + PKG_MANAGER="apk" + UPDATE_CMD="" + INSTALL_CMD="apk add" + else + echo "No supported package manager found." + return 2 + fi + + echo "Using package manager: $PKG_MANAGER" + + if [ -n "$UPDATE_CMD" ]; then + echo "Running package manager update..." + eval "$UPDATE_CMD" + fi + + FAILED_PKGS=() + + for pkg in "$@"; do + echo "Installing package: $pkg" + if ! eval "$INSTALL_CMD $pkg"; then + echo "⚠️ Warning: Failed to install package: $pkg" + FAILED_PKGS+=("$pkg") + fi + done + + if [ ${#FAILED_PKGS[@]} -ne 0 ]; then + echo "⚠️ The following packages failed to install:" + for failed_pkg in "${FAILED_PKGS[@]}"; do + echo " - $failed_pkg" + done + else + echo "✅ All requested packages installed successfully." + fi + +} + + + + +cat </etc/motd +┌───────────────────────────────────┐ +│Krayt Dragon's Lair │ +│A safe haven for volume inspection │ +└───────────────────────────────────┘ + +"Inside every volume lies a pearl of wisdom waiting to be discovered." + +Mounted Volumes: +- hi + +Persistent Volume Claims: +- hi +- hello + +Additional Packages: +- htop +- ripgrep +- uv:copier + +EOF +KRAYT_MARKER_START="# >>> Added by krayt-inject <<<" +KRAYT_MARKER_END='# <<< End krayt-inject >>>' +KRAYT_BLOCK=' +if [ -t 1 ] && [ -f /etc/motd ] && [ -z "$MOTD_SHOWN" ]; then + cat /etc/motd + export MOTD_SHOWN=1 +fi + +# fix $SHELL, not set in some distros like alpine +if [ -n "$BASH_VERSION" ]; then + export SHELL=/bin/bash +elif [ -n "$ZSH_VERSION" ]; then + export SHELL=/bin/zsh +else + export SHELL=/bin/sh +fi + +# krayt ENVIRONMENT +export KRAYT_PVCS="hi hello" + +export KRAYT_VOLUMES="hi" + +export KRAYT_ADDITIONAL_PACKAGES="htop ripgrep uv:copier" +# Universal shell initializers + +# Prompt +if command -v starship >/dev/null 2>&1; then + eval "$(starship init "$(basename "$SHELL")")" +fi + +# Smarter cd +if command -v zoxide >/dev/null 2>&1; then + eval "$(zoxide init "$(basename "$SHELL")")" +fi + +# Smarter shell history +if command -v atuin >/dev/null 2>&1; then + eval "$(atuin init "$(basename "$SHELL")")" +fi + +if command -v mcfly >/dev/null 2>&1; then + eval "$(mcfly init "$(basename "$SHELL")")" +fi + +# Directory-based environment +if command -v direnv >/dev/null 2>&1; then + eval "$(direnv hook "$(basename "$SHELL")")" +fi + +if command -v fzf >/dev/null 2>&1; then + case "$(basename "$SHELL")" in + bash|zsh|fish) + eval "$(fzf --$(basename "$SHELL"))" + ;; + *) + # shell not supported for fzf init + ;; + esac +fi +# "Did you mean...?" for mistyped commands +if command -v thefuck >/dev/null 2>&1; then + eval "$(thefuck --alias)" +fi +' +cat </etc/.kraytrc +$KRAYT_MARKER_START +$KRAYT_BLOCK +$KRAYT_MARKER_END +EOF + +KRAYT_RC_SOURCE=' +if [ -f /etc/.kraytrc ]; then + . /etc/.kraytrc +fi +' + +# List of common rc/profile files to patch +RC_FILES=" +/etc/profile +/etc/bash.bashrc +/etc/bash/bashrc +/etc/bashrc +/etc/ashrc +/etc/zsh/zshrc +/etc/zsh/zprofile +/etc/shinit +/etc/fish/config.fish +" + +echo "Searching for rc files..." + +for rc_file in $RC_FILES; do + if [ -f "$rc_file" ]; then + echo "* Found $rc_file" + + # Check if already patched + if grep -q "$KRAYT_MARKER_START" "$rc_file"; then + echo "- $rc_file already has krayt block. Skipping." + else + echo "+ Patching $rc_file" + echo "" >>"$rc_file" + echo "$KRAYT_MARKER_START" >>"$rc_file" + echo "$KRAYT_RC_SOURCE" >>"$rc_file" + echo "$KRAYT_MARKER_END" >>"$rc_file" + fi + fi +done +touch here.txt + +echo "Krayt environment ready. Sleeping forever..." +trap "echo 'Received SIGTERM. Exiting...'; exit 0" TERM +tail -f /dev/null & +wait +KRAYT_INIT_SH_EOF + +chmod +x /etc/krayt/init.sh +/etc/krayt/init.sh