From 1959e1a39b94fd349e64a54f47a5ac1c41f9c2b0 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Fri, 18 Apr 2025 13:36:05 -0500 Subject: [PATCH 01/25] replace nvim-manager with krayt --- scripts/install.sh.template | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/install.sh.template b/scripts/install.sh.template index 5fc0fb5..8e930c9 100644 --- a/scripts/install.sh.template +++ b/scripts/install.sh.template @@ -148,11 +148,11 @@ function install { FTYPE="" case "${OS}_${ARCH}" in "linux_amd64") - URL="https://github.com/WaylonWalker/nvim-manager/releases/download/v${RELEASE}/nvim-manager-${RELEASE}-x86_64-unknown-linux-gnu.tar.gz" + URL="https://github.com/WaylonWalker/krayt/releases/download/v${RELEASE}/krayt-${RELEASE}-x86_64-unknown-linux-gnu.tar.gz" FTYPE=".tar.gz" ;; "linux_arm64") - URL="https://github.com/WaylonWalker/nvim-manager/releases/download/v${RELEASE}/nvim-manager-${RELEASE}-aarch64-unknown-linux-gnu.tar.gz" + URL="https://github.com/WaylonWalker/krayt/releases/download/v${RELEASE}/krayt-${RELEASE}-aarch64-unknown-linux-gnu.tar.gz" FTYPE=".tar.gz" ;; *) fail "No asset for platform ${OS}-${ARCH}" ;; @@ -193,7 +193,7 @@ function install { unzip -o -qq tmp.zip || fail "unzip failed" rm tmp.zip || fail "cleanup failed" elif [[ $FTYPE = ".bin" ]]; then - bash -c "$GET $URL" >"nvim-manager_${OS}_${ARCH}" || fail "download failed" + bash -c "$GET $URL" >"krayt_${OS}_${ARCH}" || fail "download failed" else fail "unknown file type: $FTYPE" fi From 82102c4adff49c6decd0a1e274ff87b3ecac03e9 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Fri, 18 Apr 2025 13:36:23 -0500 Subject: [PATCH 02/25] update release notes --- scripts/get_release_notes.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/scripts/get_release_notes.py b/scripts/get_release_notes.py index d782a15..f564136 100755 --- a/scripts/get_release_notes.py +++ b/scripts/get_release_notes.py @@ -21,7 +21,11 @@ def get_release_notes(version): You can install krayt using one of these methods: -> !krayt requires [uv](https://docs.astral.sh/uv/getting-started/installation/) to be installed +## pypi + +``` bash +pip install krayt +``` ### Using i.jpillora.com (recommended) @@ -37,8 +41,8 @@ curl -fsSL https://github.com/waylonwalker/krayt/releases/download/v{version}/in ### Manual download You can also manually download the archive for your platform from the releases page: -- [x86_64-unknown-linux-gnu](https://github.com/waylonwalker/krayt/releases/download/v{version}/krayt-{version}-x86_64-unknown-linux-gnu.tar.gz) -- [aarch64-unknown-linux-gnu](https://github.com/waylonwalker/krayt/releases/download/v{version}/krayt-{version}-aarch64-unknown-linux-gnu.tar.gz)""" +- [x86_64-unknown-linux-gnu](https://github.com/waylonwalker/krayt/releases/download/v{version}/krayt-{version}-x86_64-unknown-linux-gnu) +- [aarch64-unknown-linux-gnu](https://github.com/waylonwalker/krayt/releases/download/v{version}/krayt-{version}-aarch64-unknown-linux-gnu)""" # Get help output for main command and all subcommands try: @@ -46,17 +50,23 @@ You can also manually download the archive for your platform from the releases p # Get main help output main_help = subprocess.check_output( - ["./krayt.py", "--help"], + ["krayt", "--help"], stderr=subprocess.STDOUT, universal_newlines=True, ) help_outputs.append(("Main Command", main_help)) # Get help for each subcommand - subcommands = ["create", "exec", "clean", "version"] + subcommands = [ + "create", + "exec", + "clean", + "version", + "pod", + ] for cmd in subcommands: cmd_help = subprocess.check_output( - ["./krayt.py", cmd, "--help"], + ["krayt", cmd, "--help"], stderr=subprocess.STDOUT, universal_newlines=True, ) From 2f16036c8e29f97299dfc34e4b89ef8f09b1ca2d Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Fri, 18 Apr 2025 13:36:55 -0500 Subject: [PATCH 03/25] use hatch version --- justfile | 85 +++++++++++++++++++++++--------------------------------- 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/justfile b/justfile index 8b9c260..49279c2 100644 --- a/justfile +++ b/justfile @@ -3,7 +3,7 @@ delete-tag: set -euo pipefail # Get the version - VERSION=$(cat version) + VERSION=$(hatch version) # Delete the tag git tag -d "v$VERSION" @@ -14,83 +14,66 @@ delete-release: set -euo pipefail # Get the version - VERSION=$(cat version) + VERSION=$(hatch version) # Delete the release gh release delete "v$VERSION" create-tag: #!/usr/bin/env bash - VERSION=$(cat version) + VERSION=$(hatch version) git tag -a "v$VERSION" -m "Release v$VERSION" git push origin "v$VERSION" create-archives: #!/usr/bin/env bash - VERSION=$(cat version) + VERSION=$(hatch version) rm -rf dist build - mkdir -p dist + hatch build -t binary + + krayt_bin=dist/binary/krayt-${VERSION} # Create the binary for each platform for platform in "x86_64-unknown-linux-gnu" "aarch64-unknown-linux-gnu"; do - outdir="krayt-${VERSION}-${platform}" - mkdir -p "dist/${outdir}" - + outbin="krayt-${VERSION}-${platform}" # Copy the Python script and update version - cp krayt.py "dist/${outdir}/krayt.py" - sed -i "s/NIGHTLY/${VERSION}/" "dist/${outdir}/krayt.py" - - cd dist - tar czf "${outdir}.tar.gz" "${outdir}" - sha256sum "${outdir}.tar.gz" > "${outdir}.tar.gz.sha256" - cd .. + cp ${krayt_bin} "dist/binary/${outbin}" done # Generate install.sh - ./scripts/generate_install_script.py "$VERSION" - chmod +x dist/install.sh + # ./scripts/generate_install_script.py "$VERSION" + # chmod +x dist/install.sh -create-release: create-tag create-archives +# create-release: create-archives +create-release: #!/usr/bin/env bash - VERSION=$(cat version) + VERSION=$(hatch version) ./scripts/get_release_notes.py "$VERSION" > release_notes.tmp - gh release create "v$VERSION" \ - --title "v$VERSION" \ - --notes-file release_notes.tmp \ - dist/krayt-${VERSION}-x86_64-unknown-linux-gnu.tar.gz \ - dist/krayt-${VERSION}-x86_64-unknown-linux-gnu.tar.gz.sha256 \ - dist/krayt-${VERSION}-aarch64-unknown-linux-gnu.tar.gz \ - dist/krayt-${VERSION}-aarch64-unknown-linux-gnu.tar.gz.sha256 \ - dist/install.sh + + # Check if release already exists + if gh release view "v$VERSION" &>/dev/null; then + echo "Release v$VERSION already exists. Uploading binaries..." + # Upload binaries to existing release + gh release upload "v$VERSION" \ + dist/binary/krayt-${VERSION} \ + dist/binary/krayt-${VERSION}-aarch64-unknown-linux-gnu \ + dist/binary/krayt-${VERSION}-x86_64-unknown-linux-gnu || true + else + echo "Creating new release v$VERSION" + # Create new release with binaries + gh release create "v$VERSION" \ + --title "v$VERSION" \ + --notes-file release_notes.tmp \ + dist/binary/krayt-${VERSION} \ + dist/binary/krayt-${VERSION}-aarch64-unknown-linux-gnu \ + dist/binary/krayt-${VERSION}-x86_64-unknown-linux-gnu + fi rm release_notes.tmp preview-release-notes: #!/usr/bin/env bash - VERSION=$(cat version) + VERSION=$(hatch version) ./scripts/get_release_notes.py "$VERSION" | less -R release: create-release -build-pyapp: - export PYAPP_PROJECT_NAME=krayt - export PYAPP_PROJECT_VERSION=`hatch version` - export PYAPP_DISTRIBUTION_SOURCE=~/git/krayt/dist/krayt-${PYAPP_PROJECT_VERSION}.tar.gz - export PYAPP_DISTRIBUTION_EMBED=true - - - echo "linting" - hatch run lint-format - - echo "Building pyapp" - hatch build - - echo "Uploading pyapp" - hatch publish - - cd ~/git/pyapp - cargo build --release --quiet - - - echo "Done" - - From ae918bf5f27124ce4658a7055a7cbcbe312a6cf5 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Fri, 18 Apr 2025 13:37:11 -0500 Subject: [PATCH 04/25] changelog for 0.3.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f04f65..40950cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.3.0 + +- created pypi release +- updated releases to use pyapp +- all new package +- port forward support +- additional_packages support + ## 0.2.0 ### Added From cc425cf812bb58437418fc5a8813855f14730237 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Fri, 18 Apr 2025 13:38:05 -0500 Subject: [PATCH 05/25] add --apply flag for create --- CHANGELOG.md | 4 +++ krayt/cli/pod.py | 65 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40950cf..b32f5e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.0 + +- create now has --apply to apply the generated manifest to the cluster + ## 0.3.0 - created pypi release diff --git a/krayt/cli/pod.py b/krayt/cli/pod.py index 6cf9aa3..1417247 100644 --- a/krayt/cli/pod.py +++ b/krayt/cli/pod.py @@ -144,6 +144,17 @@ def get_pods( raise typer.Exit(1) +def get_namespaces( + namespace=None, + label_selector: str = "app=krayt", +): + config.load_kube_config() + api = client.CoreV1Api() + + all_namespaces = [n.metadata.name for n in api.list_namespace().items] + return all_namespaces + + def get_pod_spec(pod_name, namespace): config.load_kube_config() v1 = client.CoreV1Api() @@ -640,6 +651,11 @@ def create( "--post-init-hooks", help="additional hooks to execute at the start of container initialization", ), + apply: bool = typer.Option( + False, + "--apply", + help="Automatically apply the changes instead of just echoing them.", + ), ): """ Krack open a Krayt dragon! Create an inspector pod to explore what's inside your volumes. @@ -647,16 +663,15 @@ def create( The inspector will be created in the same namespace as the selected pod. """ # For create, we want to list all pods, not just Krayt pods - selected_namespace = None - selected_pod = None + selected_namespace = namespace + selected_pod = clone if namespace is None and clone is not None and "/" in clone: selected_namespace, selected_pod = clone.split("/", 1) - elif namespace is not None and clone is not None: - selected_namespace = namespace - selected_pod = clone - pods = get_pods(namespace, label_selector=None) + namepaces = get_namespaces(namespace) + pods = get_pods(namespace, label_selector="app!=krayt") + if not pods: typer.echo("No pods found.") raise typer.Exit(1) @@ -694,7 +709,43 @@ def create( ) # Output the job manifest - typer.echo(yaml.dump(clean_dict(inspector_job), sort_keys=False)) + job_yaml = yaml.dump(clean_dict(inspector_job), sort_keys=False) + + if apply: + # # Apply the job to the cluster + # import tempfile + # import subprocess + # + # with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml") as temp_file: + # temp_file.write(job_yaml) + # temp_file.flush() + # + # try: + # typer.echo( + # f"Applying job {job_name} to namespace {selected_namespace}..." + # ) + # result = subprocess.run( + # ["kubectl", "apply", "-f", temp_file.name], + # capture_output=True, + # text=True, + # check=True, + # ) + # typer.echo(result.stdout) + # typer.echo(f"Successfully created inspector job {job_name}") + # except subprocess.CalledProcessError as e: + # typer.echo(f"Error applying job: {e.stderr}", err=True) + # raise typer.Exit(1) + # + batch_api = client.BatchV1Api() + job = batch_api.create_namespaced_job( + namespace=selected_namespace, + body=inspector_job, + ) + print(f"Job {job.metadata.name} created.") + return job + else: + # Just echo the YAML + typer.echo(job_yaml) @app.command() From 7daa9a3874780640f6ada8d6c3fd570ddc0676a5 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Fri, 18 Apr 2025 14:05:48 -0500 Subject: [PATCH 06/25] python native exec --- krayt/cli/pod.py | 281 ++++++++++++++++++++++++++++------------------- 1 file changed, 170 insertions(+), 111 deletions(-) diff --git a/krayt/cli/pod.py b/krayt/cli/pod.py index 1417247..9107b7b 100644 --- a/krayt/cli/pod.py +++ b/krayt/cli/pod.py @@ -1,5 +1,6 @@ import iterfzf from krayt.templates import env +from kubernetes.stream import stream from kubernetes import client, config import logging import os @@ -8,6 +9,10 @@ import typer from typing import Any, List, Optional import yaml from krayt.__about__ import __version__ +import sys +import tty +import termios +import select logging.basicConfig(level=logging.WARNING) @@ -35,8 +40,8 @@ def format_volume_mount(vm: client.V1VolumeMount) -> dict[str, Any]: return clean_dict( { "name": vm.name, - "mountPath": vm.mount_path, - "readOnly": vm.read_only if vm.read_only else None, + "mount_path": vm.mount_path, + "read_only": vm.read_only if vm.read_only else None, } ) @@ -271,92 +276,81 @@ def create_inspector_job( pre_init_hooks: Optional[List[str]] = None, post_init_hooks: Optional[List[str]] = None, ): - """Create a Krayt inspector job with the given mounts""" timestamp = int(time.time()) job_name = f"{pod_name}-krayt-{timestamp}" - # Get environment variables and secret volumes from the target pod env_vars, secret_volumes = get_env_vars_and_secret_volumes(api, namespace) - - # Add secret volumes to our volumes list volumes.extend(secret_volumes) - # Create corresponding volume mounts for secrets - secret_mounts = [] - for vol in secret_volumes: - secret_mounts.append( - { - "name": vol.name, - "mountPath": f"/mnt/secrets/{vol.secret.secret_name}", - "readOnly": True, - } + secret_mounts = [ + client.V1VolumeMount( + name=vol.name, + mount_path=f"/mnt/secrets/{vol.secret.secret_name}", + read_only=True, ) + for vol in secret_volumes + ] - # Convert volume mounts to dictionaries formatted_mounts = [format_volume_mount(vm) for vm in volume_mounts] + formatted_mounts = [client.V1VolumeMount(**vm) for vm in formatted_mounts if vm] formatted_mounts.extend(secret_mounts) - # Format mount and PVC info for MOTD - mount_info = [] - for vm in formatted_mounts: - if vm: - mount_info.append(f"{vm['name']}:{vm['mountPath']}") + pvc_info = [ + f"{v.name}:{v.persistent_volume_claim.claim_name}" + for v in volumes + if hasattr(v, "persistent_volume_claim") and v.persistent_volume_claim + ] - pvc_info = [] - for v in volumes: - if hasattr(v, "persistent_volume_claim") and v.persistent_volume_claim: - pvc_info.append(f"{v.name}:{v.persistent_volume_claim.claim_name}") - - template_name = "base.sh" - template = env.get_template(template_name) - pvcs = None - pre_init_scripts = None - post_init_scripts = None - pre_init_hooks = None - post_init_hooks = None + template = env.get_template("base.sh") command = template.render( volumes=volumes, - pvcs=pvcs, + pvcs=None, 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, + pre_init_scripts=None, + post_init_scripts=None, + pre_init_hooks=None, + post_init_hooks=None, ) - inspector_job = { - "apiVersion": "batch/v1", - "kind": "Job", - "metadata": { - "name": job_name, - "namespace": namespace, - "labels": {"app": "krayt"}, - "annotations": {"pvcs": ",".join(pvc_info) if pvc_info else "none"}, - }, - "spec": { - "ttlSecondsAfterFinished": 600, - "template": { - "metadata": {"labels": {"app": "krayt"}}, - "spec": { - "containers": [ - { - "name": "inspector", - "image": image, - "command": ["sh", "-c", command], - "env": env_vars, - "volumeMounts": formatted_mounts, - } - ], - "volumes": [format_volume(v) for v in volumes if format_volume(v)], - "imagePullSecrets": [{"name": imagepullsecret}] - if imagepullsecret - else None, - "restartPolicy": "Never", - }, - }, - }, - } - return inspector_job + container = client.V1Container( + name="inspector", + image=image, + command=["sh", "-c", command], + env=env_vars, + volume_mounts=formatted_mounts, + ) + + spec = client.V1PodSpec( + containers=[container], + volumes=[format_volume(v) for v in volumes if format_volume(v)], + restart_policy="Never", + image_pull_secrets=[client.V1LocalObjectReference(name=imagepullsecret)] + if imagepullsecret + else None, + ) + + template = client.V1PodTemplateSpec( + metadata=client.V1ObjectMeta(labels={"app": "krayt"}), spec=spec + ) + + job_spec = client.V1JobSpec( + template=template, + ttl_seconds_after_finished=600, + ) + + job = client.V1Job( + api_version="batch/v1", + kind="Job", + metadata=client.V1ObjectMeta( + name=job_name, + namespace=namespace, + labels={"app": "krayt"}, + annotations={"pvcs": ",".join(pvc_info) if pvc_info else "none"}, + ), + spec=job_spec, + ) + + return job PROTECTED_NAMESPACES = { @@ -449,6 +443,89 @@ def get_pod(namespace: Optional[str] = None): return pod_name, pod_namespace +# @app.command() +# def exec( +# namespace: Optional[str] = typer.Option( +# None, +# help="Kubernetes namespace. If not specified, will search for inspectors across all namespaces.", +# ), +# ): +# """ +# Enter the Krayt dragon's lair! Connect to a running inspector pod. +# If multiple inspectors are found, you'll get to choose which one to explore. +# """ +# +# pod_name, pod_namespace = get_pod(namespace) +# exec_command = [ +# "kubectl", +# "exec", +# "-it", +# "-n", +# pod_namespace, +# pod_name, +# "--", +# "/bin/bash", +# "-l", +# ] +# +# os.execvp("kubectl", exec_command) + + +def interactive_exec(pod_name: str, namespace: str): + # Load kubeconfig from local context (or use load_incluster_config if running inside the cluster) + config.load_kube_config() + + core_v1 = client.CoreV1Api() + command = ["/bin/bash", "-i"] + + # Save the current terminal settings + oldtty = termios.tcgetattr(sys.stdin) + try: + # Put terminal into raw mode but don't handle local echo ourselves + # Let the remote terminal handle echoing and control characters + tty.setraw(sys.stdin.fileno()) + + # Create a TTY-enabled exec connection to the pod + resp = stream( + core_v1.connect_get_namespaced_pod_exec, + pod_name, + namespace, + command=command, + stderr=True, + stdin=True, + stdout=True, + tty=True, + _preload_content=False, + ) + + # Set up a simple select-based event loop to handle I/O + while resp.is_open(): + # Update the websocket connection + resp.update(timeout=0.1) + + # Handle output from the pod + if resp.peek_stdout(): + sys.stdout.write(resp.read_stdout()) + sys.stdout.flush() + if resp.peek_stderr(): + sys.stderr.write(resp.read_stderr()) + sys.stderr.flush() + + # Check for input from the user + rlist, _, _ = select.select([sys.stdin], [], [], 0.01) + if sys.stdin in rlist: + # Read input and forward it to the pod without local echo + data = os.read(sys.stdin.fileno(), 1024) + if data: + resp.write_stdin(data.decode()) + + except Exception as e: + print(f"\nError in interactive session: {e}", file=sys.stderr) + finally: + # Always restore terminal settings + termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) + + @app.command() def exec( namespace: Optional[str] = typer.Option( @@ -460,21 +537,28 @@ def exec( Enter the Krayt dragon's lair! Connect to a running inspector pod. If multiple inspectors are found, you'll get to choose which one to explore. """ + config.load_kube_config() # or config.load_incluster_config() if running inside a pod + core_v1 = client.CoreV1Api() pod_name, pod_namespace = get_pod(namespace) - exec_command = [ - "kubectl", - "exec", - "-it", - "-n", - pod_namespace, - pod_name, - "--", - "/bin/bash", - "-l", - ] + interactive_exec(pod_name, pod_namespace) - os.execvp("kubectl", exec_command) + # command = ["/bin/bash", "-l"] + # print(f"kubectl exec -it -n {pod_namespace} {pod_name} -- {' '.join(command)}") + # print( + # f"execing into {pod_name} in {pod_namespace} with command {' '.join(command)}" + # ) + # resp = stream( + # core_v1.connect_get_namespaced_pod_exec, + # pod_name, + # pod_namespace, + # command=command, + # stderr=True, + # stdin=True, + # stdout=True, + # tty=True, + # ) + # print(resp) @app.command() @@ -687,9 +771,6 @@ 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})") - pod_spec = get_pod_spec(selected_pod, selected_namespace) volume_mounts, volumes = get_pod_volumes_and_mounts(pod_spec) @@ -709,33 +790,11 @@ def create( ) # Output the job manifest - job_yaml = yaml.dump(clean_dict(inspector_job), sort_keys=False) + api_client = client.ApiClient() + job_dict = api_client.sanitize_for_serialization(inspector_job) + job_yaml = yaml.dump(job_dict, sort_keys=False) if apply: - # # Apply the job to the cluster - # import tempfile - # import subprocess - # - # with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml") as temp_file: - # temp_file.write(job_yaml) - # temp_file.flush() - # - # try: - # typer.echo( - # f"Applying job {job_name} to namespace {selected_namespace}..." - # ) - # result = subprocess.run( - # ["kubectl", "apply", "-f", temp_file.name], - # capture_output=True, - # text=True, - # check=True, - # ) - # typer.echo(result.stdout) - # typer.echo(f"Successfully created inspector job {job_name}") - # except subprocess.CalledProcessError as e: - # typer.echo(f"Error applying job: {e.stderr}", err=True) - # raise typer.Exit(1) - # batch_api = client.BatchV1Api() job = batch_api.create_namespaced_job( namespace=selected_namespace, From 3ce69baf261784d4d2ee11f918e369fb3778d129 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Mon, 21 Apr 2025 09:46:03 -0500 Subject: [PATCH 07/25] generic templates endpoint for cli --- CHANGELOG.md | 1 + krayt/cli/__init__.py | 2 +- krayt/cli/templates.py | 72 +++++++++++++++++++++--------------------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b32f5e9..075d211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.4.0 - create now has --apply to apply the generated manifest to the cluster +- generic templates endpoint for cli ## 0.3.0 diff --git a/krayt/cli/__init__.py b/krayt/cli/__init__.py index d5c6f0c..035a6de 100644 --- a/krayt/cli/__init__.py +++ b/krayt/cli/__init__.py @@ -6,7 +6,7 @@ from typer import Typer app = Typer() -app.add_typer(templates_app, name="templates", no_args_is_help=True) +app.add_typer(templates_app, name="template", 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) diff --git a/krayt/cli/templates.py b/krayt/cli/templates.py index 841cd54..7416db6 100644 --- a/krayt/cli/templates.py +++ b/krayt/cli/templates.py @@ -13,7 +13,8 @@ def list(): @app.command() -def base( +def render( + template_name: Optional[str] = typer.Option("base.sh", "--template-name", "-t"), volumes: Optional[List[str]] = typer.Option( None, "--volume", @@ -48,7 +49,6 @@ def base( help="additional hooks to execute at the start of container initialization", ), ): - template_name = "base.sh" template = env.get_template(template_name) rendered = template.render( volumes=volumes, @@ -62,37 +62,37 @@ def base( print(rendered) -@app.command() -def install( - additional_packages: Optional[List[str]] = typer.Option( - ..., "--additional-packages", "-ap" - ), -): - template_name = "install.sh" - template = env.get_template(template_name) - rendered = template.render(additional_packages=additional_packages) - print(rendered) - - -@app.command() -def motd( - volumes: Optional[List[str]] = typer.Option( - None, - "--volume", - ), - pvcs: Optional[List[str]] = typer.Option( - None, - "--pvc", - ), - additional_packages: Optional[List[str]] = typer.Option( - ..., "--additional-packages", "-ap" - ), -): - template_name = "motd.sh" - template = env.get_template(template_name) - rendered = template.render( - volumes=volumes, - pvcs=pvcs, - additional_packages=additional_packages, - ) - print(rendered) +# @app.command() +# def install( +# additional_packages: Optional[List[str]] = typer.Option( +# ..., "--additional-packages", "-ap" +# ), +# ): +# template_name = "install.sh" +# template = env.get_template(template_name) +# rendered = template.render(additional_packages=additional_packages) +# print(rendered) +# +# +# @app.command() +# def motd( +# volumes: Optional[List[str]] = typer.Option( +# None, +# "--volume", +# ), +# pvcs: Optional[List[str]] = typer.Option( +# None, +# "--pvc", +# ), +# additional_packages: Optional[List[str]] = typer.Option( +# ..., "--additional-packages", "-ap" +# ), +# ): +# template_name = "motd.sh" +# template = env.get_template(template_name) +# rendered = template.render( +# volumes=volumes, +# pvcs=pvcs, +# additional_packages=additional_packages, +# ) +# print(rendered) From db968536463aa1bf55a5a5c34eb14ff851263660 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Mon, 21 Apr 2025 09:47:31 -0500 Subject: [PATCH 08/25] add python fallback for exec --- krayt/cli/pod.py | 196 +++++++++++++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 76 deletions(-) diff --git a/krayt/cli/pod.py b/krayt/cli/pod.py index 9107b7b..4c81f19 100644 --- a/krayt/cli/pod.py +++ b/krayt/cli/pod.py @@ -13,6 +13,8 @@ import sys import tty import termios import select +import signal +import json logging.basicConfig(level=logging.WARNING) @@ -443,87 +445,121 @@ def get_pod(namespace: Optional[str] = None): return pod_name, pod_namespace -# @app.command() -# def exec( -# namespace: Optional[str] = typer.Option( -# None, -# help="Kubernetes namespace. If not specified, will search for inspectors across all namespaces.", -# ), -# ): -# """ -# Enter the Krayt dragon's lair! Connect to a running inspector pod. -# If multiple inspectors are found, you'll get to choose which one to explore. -# """ -# -# pod_name, pod_namespace = get_pod(namespace) -# exec_command = [ -# "kubectl", -# "exec", -# "-it", -# "-n", -# pod_namespace, -# pod_name, -# "--", -# "/bin/bash", -# "-l", -# ] -# -# os.execvp("kubectl", exec_command) - - def interactive_exec(pod_name: str, namespace: str): # Load kubeconfig from local context (or use load_incluster_config if running inside the cluster) - config.load_kube_config() + print(f"Connecting to pod {pod_name} in namespace {namespace}...") + try: + config.load_kube_config() + except Exception as e: + print(f"Error loading kubeconfig: {e}", file=sys.stderr) + return core_v1 = client.CoreV1Api() - command = ["/bin/bash", "-i"] + command = ["/bin/bash", "-l"] + resp = None # Save the current terminal settings oldtty = termios.tcgetattr(sys.stdin) + + # Function to handle window resize events + def handle_resize(signum, frame): + if resp and resp.is_open(): + # Get the current terminal size + cols, rows = os.get_terminal_size() + # Send terminal resize command via websocket + # Format matches kubectl's resize message format + resize_msg = json.dumps({"Width": cols, "Height": rows}) + resp.write_channel(4, resize_msg) + + # Function to handle exit signals + def handle_exit(signum, frame): + if resp and resp.is_open(): + # Send Ctrl+C to the remote process + resp.write_stdin("\x03") + try: # Put terminal into raw mode but don't handle local echo ourselves # Let the remote terminal handle echoing and control characters tty.setraw(sys.stdin.fileno()) - + + # Set up signal handlers + signal.signal(signal.SIGWINCH, handle_resize) # Window resize + signal.signal(signal.SIGINT, handle_exit) # Ctrl+C + # Create a TTY-enabled exec connection to the pod - resp = stream( - core_v1.connect_get_namespaced_pod_exec, - pod_name, - namespace, - command=command, - stderr=True, - stdin=True, - stdout=True, - tty=True, - _preload_content=False, - ) + try: + resp = stream( + core_v1.connect_get_namespaced_pod_exec, + pod_name, + namespace, + command=command, + stderr=True, + stdin=True, + stdout=True, + tty=True, + _preload_content=False, + ) + print(f"Connected to {pod_name}") + except Exception as e: + print(f"\nError connecting to pod: {e}", file=sys.stderr) + return + + # Wait for the connection to be ready + time.sleep(0.2) + + # Send initial terminal size + cols, rows = os.get_terminal_size() + resize_msg = json.dumps({"Width": cols, "Height": rows}) + resp.write_channel(4, resize_msg) + + # Make sure the size is set by sending a resize event + handle_resize(None, None) # Set up a simple select-based event loop to handle I/O - while resp.is_open(): - # Update the websocket connection - resp.update(timeout=0.1) - - # Handle output from the pod - if resp.peek_stdout(): - sys.stdout.write(resp.read_stdout()) - sys.stdout.flush() - if resp.peek_stderr(): - sys.stderr.write(resp.read_stderr()) - sys.stderr.flush() + try: + while resp and resp.is_open(): + # Update the websocket connection + resp.update(timeout=0.1) - # Check for input from the user - rlist, _, _ = select.select([sys.stdin], [], [], 0.01) - if sys.stdin in rlist: - # Read input and forward it to the pod without local echo - data = os.read(sys.stdin.fileno(), 1024) - if data: + # Handle output from the pod + if resp.peek_stdout(): + sys.stdout.write(resp.read_stdout()) + sys.stdout.flush() + if resp.peek_stderr(): + sys.stderr.write(resp.read_stderr()) + sys.stderr.flush() + + # Check for input from the user + rlist, _, _ = select.select([sys.stdin], [], [], 0.01) + if sys.stdin in rlist: + # Read input and forward it to the pod without local echo + data = os.read(sys.stdin.fileno(), 1024) + if not data: # EOF (e.g., user pressed Ctrl+D) + break resp.write_stdin(data.decode()) + except Exception as e: + print(f"\nConnection error: {e}", file=sys.stderr) + except KeyboardInterrupt: + # Handle Ctrl+C gracefully + print("\nSession terminated by user", file=sys.stderr) except Exception as e: print(f"\nError in interactive session: {e}", file=sys.stderr) finally: + # Reset signal handlers + signal.signal(signal.SIGWINCH, signal.SIG_DFL) + signal.signal(signal.SIGINT, signal.SIG_DFL) + + # Close the connection if it's still open + if resp and resp.is_open(): + try: + resp.close() + except: + pass + # Always restore terminal settings termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) + print("\nConnection closed", file=sys.stderr) @app.command() @@ -532,6 +568,12 @@ def exec( None, help="Kubernetes namespace. If not specified, will search for inspectors across all namespaces.", ), + shell: Optional[str] = typer.Option( + "/bin/bash", + "--shell", + "-s", + help="Shell to use for the inspector pod", + ), ): """ Enter the Krayt dragon's lair! Connect to a running inspector pod. @@ -541,24 +583,26 @@ def exec( core_v1 = client.CoreV1Api() pod_name, pod_namespace = get_pod(namespace) - interactive_exec(pod_name, pod_namespace) - # command = ["/bin/bash", "-l"] - # print(f"kubectl exec -it -n {pod_namespace} {pod_name} -- {' '.join(command)}") - # print( - # f"execing into {pod_name} in {pod_namespace} with command {' '.join(command)}" - # ) - # resp = stream( - # core_v1.connect_get_namespaced_pod_exec, - # pod_name, - # pod_namespace, - # command=command, - # stderr=True, - # stdin=True, - # stdout=True, - # tty=True, - # ) - # print(resp) + try: + pod_name, pod_namespace = get_pod(namespace) + exec_command = [ + "kubectl", + "exec", + "-it", + "-n", + pod_namespace, + pod_name, + "--", + shell, + "-l", + ] + + os.execvp("kubectl", exec_command) + except Exception as e: + print(f"Error executing command with kubectl trying python api: {e}") + + interactive_exec(pod_name, pod_namespace) @app.command() From 225edce32d24f11fe53eb3712760a1190287a69b Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 19:42:40 -0500 Subject: [PATCH 09/25] better motd volumes --- krayt/templates/motd.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/krayt/templates/motd.sh b/krayt/templates/motd.sh index 9de1e85..5838161 100644 --- a/krayt/templates/motd.sh +++ b/krayt/templates/motd.sh @@ -5,11 +5,11 @@ cat </etc/motd └───────────────────────────────────┘ "Inside every volume lies a pearl of wisdom waiting to be discovered." -{%- if volumes %} +{%- if mounts %} Mounted Volumes: -{%- for volume in volumes %} -- {{ volume }} +{%- for mount in mounts %} +- {{ mount.name }}:{{ mount.mount_path }} {%- endfor %} {%- endif %} From 17c088526b8c4d5abe4d7c1c6849639d748a6231 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 19:56:26 -0500 Subject: [PATCH 10/25] release 0.4.0 --- .github/workflows/release-pypi.yaml | 11 +++++++++++ CHANGELOG.md | 1 + justfile | 4 ++-- krayt/__about__.py | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index bd6c6ab..162de46 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -22,3 +22,14 @@ jobs: env: # required for gh release GH_TOKEN: ${{ github.token }} + - name: Install just + run: | + curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to DEST + shell: bash + - name: Install uv + run: | + curl -LsSf https://astral.sh/uv/0.6.16/install.sh | sh + shell: bash + - name: GitHub Release (just release) + run: just create-release + shell: bash diff --git a/CHANGELOG.md b/CHANGELOG.md index 075d211..e6265dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - create now has --apply to apply the generated manifest to the cluster - generic templates endpoint for cli +- better motd for volume mounts ## 0.3.0 diff --git a/justfile b/justfile index 49279c2..5e9b035 100644 --- a/justfile +++ b/justfile @@ -44,8 +44,8 @@ create-archives: # ./scripts/generate_install_script.py "$VERSION" # chmod +x dist/install.sh -# create-release: create-archives -create-release: +create-release: create-tag create-archives +# create-release: #!/usr/bin/env bash VERSION=$(hatch version) ./scripts/get_release_notes.py "$VERSION" > release_notes.tmp diff --git a/krayt/__about__.py b/krayt/__about__.py index 493f741..dab8f5a 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.3.0" +__version__ = "0.4.0b0" From ed449034f70c30d65a462cd50636ea1c3458d623 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 19:59:15 -0500 Subject: [PATCH 11/25] formatting fix --- krayt/cli/pod.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/krayt/cli/pod.py b/krayt/cli/pod.py index 4c81f19..d8ac87a 100644 --- a/krayt/cli/pod.py +++ b/krayt/cli/pod.py @@ -554,7 +554,7 @@ def interactive_exec(pod_name: str, namespace: str): if resp and resp.is_open(): try: resp.close() - except: + except Exception: pass # Always restore terminal settings @@ -580,7 +580,7 @@ def exec( If multiple inspectors are found, you'll get to choose which one to explore. """ config.load_kube_config() # or config.load_incluster_config() if running inside a pod - core_v1 = client.CoreV1Api() + client.CoreV1Api() pod_name, pod_namespace = get_pod(namespace) @@ -797,7 +797,7 @@ def create( if namespace is None and clone is not None and "/" in clone: selected_namespace, selected_pod = clone.split("/", 1) - namepaces = get_namespaces(namespace) + get_namespaces(namespace) pods = get_pods(namespace, label_selector="app!=krayt") if not pods: @@ -916,10 +916,10 @@ def list_pods(): typer.echo(f"{pod} ({namespace})") -def main(): - setup_environment() - app() - - -if __name__ == "__main__": - main() +# def main(): +# setup_environment() +# app() +# +# +# if __name__ == "__main__": +# main() From 681194fc1f58612e89a765ae0a8fd58724ce68cb Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:00:20 -0500 Subject: [PATCH 12/25] fix justfile format --- justfile | 1 - 1 file changed, 1 deletion(-) diff --git a/justfile b/justfile index 5e9b035..f62f5c9 100644 --- a/justfile +++ b/justfile @@ -45,7 +45,6 @@ create-archives: # chmod +x dist/install.sh create-release: create-tag create-archives -# create-release: #!/usr/bin/env bash VERSION=$(hatch version) ./scripts/get_release_notes.py "$VERSION" > release_notes.tmp From 64077d3ba2122ffbf3ebd495778072fa0088f3a4 Mon Sep 17 00:00:00 2001 From: WaylonWalker Date: Thu, 24 Apr 2025 01:01:32 +0000 Subject: [PATCH 13/25] =?UTF-8?q?Bump=20version:=200.4.0b0=20=E2=86=92=200?= =?UTF-8?q?.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- krayt/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/krayt/__about__.py b/krayt/__about__.py index dab8f5a..6a9beea 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.0b0" +__version__ = "0.4.0" From 0a6e19731d8db9f0ce432deb9dfd91798792c3c1 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:04:02 -0500 Subject: [PATCH 14/25] fix just install --- .github/workflows/release-pypi.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index 162de46..8fbadca 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -16,15 +16,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: waylonwalker/hatch-action@v4 - with: - before-command: "lint-format" - env: - # required for gh release - GH_TOKEN: ${{ github.token }} + # - uses: waylonwalker/hatch-action@v4 + # with: + # before-command: "lint-format" + # env: + # # required for gh release + # GH_TOKEN: ${{ github.token }} - name: Install just run: | - curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to DEST + curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin shell: bash - name: Install uv run: | From 1138f695f47cf3bfbdedb32b6dcf97be00964002 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:04:59 -0500 Subject: [PATCH 15/25] bump action --- .github/workflows/release-pypi.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index 8fbadca..e7b47e7 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -22,6 +22,7 @@ jobs: # env: # # required for gh release # GH_TOKEN: ${{ github.token }} + # - name: Install just run: | curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin From 7511cace421efe8c0a965439ed0efed0d81e683b Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:05:43 -0500 Subject: [PATCH 16/25] bump build --- krayt/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/krayt/__about__.py b/krayt/__about__.py index 6a9beea..6f9c9b3 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.0" +__version__ = "0.4.1b0" From b64e635b714564c2ff3017fd2141f5036fe035b1 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:09:52 -0500 Subject: [PATCH 17/25] install hatch for release --- .github/workflows/release-pypi.yaml | 11 +++++++++++ krayt/__about__.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index e7b47e7..f1a6c3e 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -31,6 +31,17 @@ jobs: run: | curl -LsSf https://astral.sh/uv/0.6.16/install.sh | sh shell: bash + - name: Install hatch + run: | + uv pip install hatch --system + shell: bash + - name: Configure Git + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + shell: bash - name: GitHub Release (just release) run: just create-release + env: + GH_TOKEN: ${{ github.token }} shell: bash diff --git a/krayt/__about__.py b/krayt/__about__.py index 6f9c9b3..ea0e418 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.1b0" +__version__ = "0.4.1b1" From 2fbc15ae8492385b92caadff51c9ca211f832f9a Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:11:13 -0500 Subject: [PATCH 18/25] use uv tool --- .github/workflows/release-pypi.yaml | 2 +- krayt/__about__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index f1a6c3e..78cba98 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -33,7 +33,7 @@ jobs: shell: bash - name: Install hatch run: | - uv pip install hatch --system + uv tool install hatch shell: bash - name: Configure Git run: | diff --git a/krayt/__about__.py b/krayt/__about__.py index ea0e418..04e30ea 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.1b1" +__version__ = "0.4.1b2" From 1fee6e2c97be2fc1b8db531a8167b4678eb628ca Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:19:57 -0500 Subject: [PATCH 19/25] fix deployment --- justfile | 2 +- krayt/__about__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/justfile b/justfile index f62f5c9..35dfece 100644 --- a/justfile +++ b/justfile @@ -31,7 +31,7 @@ create-archives: rm -rf dist build hatch build -t binary - krayt_bin=dist/binary/krayt-${VERSION} + krayt_bin=dist/binary/krayt-${VERSION}/krayt_linux_amd64 # Create the binary for each platform for platform in "x86_64-unknown-linux-gnu" "aarch64-unknown-linux-gnu"; do diff --git a/krayt/__about__.py b/krayt/__about__.py index 04e30ea..7c5a130 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.1b2" +__version__ = "0.4.1b3" From be6ee910981561226d56d404329bf25baad60bb6 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:28:57 -0500 Subject: [PATCH 20/25] release 0.4.1 --- .github/workflows/release-pypi.yaml | 13 ++++++------- CHANGELOG.md | 4 ++++ justfile | 2 +- krayt/__about__.py | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index 78cba98..1e607ef 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -16,13 +16,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - # - uses: waylonwalker/hatch-action@v4 - # with: - # before-command: "lint-format" - # env: - # # required for gh release - # GH_TOKEN: ${{ github.token }} - # + - uses: waylonwalker/hatch-action@v4 + with: + before-command: "lint-format" + env: + # required for gh release + GH_TOKEN: ${{ github.token }} - name: Install just run: | curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin diff --git a/CHANGELOG.md b/CHANGELOG.md index e6265dc..a158339 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +- Automated release for both pypi and github + ## 0.4.0 - create now has --apply to apply the generated manifest to the cluster diff --git a/justfile b/justfile index 35dfece..f62f5c9 100644 --- a/justfile +++ b/justfile @@ -31,7 +31,7 @@ create-archives: rm -rf dist build hatch build -t binary - krayt_bin=dist/binary/krayt-${VERSION}/krayt_linux_amd64 + krayt_bin=dist/binary/krayt-${VERSION} # Create the binary for each platform for platform in "x86_64-unknown-linux-gnu" "aarch64-unknown-linux-gnu"; do diff --git a/krayt/__about__.py b/krayt/__about__.py index 7c5a130..a79b352 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.1b3" +__version__ = "0.4.1b4" From d6056cead2e8aa7275e66d85a0e3d265cfa27d73 Mon Sep 17 00:00:00 2001 From: WaylonWalker Date: Thu, 24 Apr 2025 01:36:32 +0000 Subject: [PATCH 21/25] =?UTF-8?q?Bump=20version:=200.4.1b4=20=E2=86=92=200?= =?UTF-8?q?.4.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- krayt/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/krayt/__about__.py b/krayt/__about__.py index a79b352..3d26edf 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.1b4" +__version__ = "0.4.1" From eb54e314ff4f495ab839e42a0cce79a1d7e0f09f Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:40:38 -0500 Subject: [PATCH 22/25] release 0.4.2 --- .github/workflows/release-pypi.yaml | 5 ++++- CHANGELOG.md | 4 ++++ krayt/__about__.py | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index 1e607ef..8aead5b 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -12,7 +12,7 @@ permissions: packages: none id-token: write jobs: - release-krayt: + pypi-release-krayt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -22,6 +22,9 @@ jobs: env: # required for gh release GH_TOKEN: ${{ github.token }} + gh-release-krayt: + runs-on: ubuntu-latest + steps: - name: Install just run: | curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin diff --git a/CHANGELOG.md b/CHANGELOG.md index a158339..cc6a106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.2 + +- working out binary release process + ## 0.4.1 - Automated release for both pypi and github diff --git a/krayt/__about__.py b/krayt/__about__.py index 3d26edf..d54ab1b 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.1" +__version__ = "0.4.2b0" From 45e5dd74aaea0a1b1af19300ee1f6cdd112f9c86 Mon Sep 17 00:00:00 2001 From: WaylonWalker Date: Thu, 24 Apr 2025 01:42:32 +0000 Subject: [PATCH 23/25] =?UTF-8?q?Bump=20version:=200.4.2b0=20=E2=86=92=200?= =?UTF-8?q?.4.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- krayt/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/krayt/__about__.py b/krayt/__about__.py index d54ab1b..df12433 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.2b0" +__version__ = "0.4.2" From f8c44999fe1f0d6e98e9c651d35c27477d48fba2 Mon Sep 17 00:00:00 2001 From: "Waylon S. Walker" Date: Wed, 23 Apr 2025 20:45:16 -0500 Subject: [PATCH 24/25] release 0.4.3 --- .github/workflows/release-pypi.yaml | 4 +--- CHANGELOG.md | 4 ++++ krayt/__about__.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index 8aead5b..16111e2 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -22,9 +22,7 @@ jobs: env: # required for gh release GH_TOKEN: ${{ github.token }} - gh-release-krayt: - runs-on: ubuntu-latest - steps: + - run: sudo rm -rf dist - name: Install just run: | curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin diff --git a/CHANGELOG.md b/CHANGELOG.md index cc6a106..29ffba6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.3 + +- working out binary release process + ## 0.4.2 - working out binary release process diff --git a/krayt/__about__.py b/krayt/__about__.py index df12433..6d91c22 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.2" +__version__ = "0.4.3b0" From 0f9e70267ecefbc0a9803e1232906971835a10e1 Mon Sep 17 00:00:00 2001 From: WaylonWalker Date: Thu, 24 Apr 2025 01:46:17 +0000 Subject: [PATCH 25/25] =?UTF-8?q?Bump=20version:=200.4.3b0=20=E2=86=92=200?= =?UTF-8?q?.4.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- krayt/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/krayt/__about__.py b/krayt/__about__.py index 6d91c22..f6b7e26 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.3b0" +__version__ = "0.4.3"