diff --git a/.github/workflows/release-pypi.yaml b/.github/workflows/release-pypi.yaml index 16111e2..bd6c6ab 100644 --- a/.github/workflows/release-pypi.yaml +++ b/.github/workflows/release-pypi.yaml @@ -12,7 +12,7 @@ permissions: packages: none id-token: write jobs: - pypi-release-krayt: + release-krayt: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -22,26 +22,3 @@ jobs: env: # required for gh release GH_TOKEN: ${{ github.token }} - - 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 - shell: bash - - name: Install uv - run: | - curl -LsSf https://astral.sh/uv/0.6.16/install.sh | sh - shell: bash - - name: Install hatch - run: | - uv tool install hatch - 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/CHANGELOG.md b/CHANGELOG.md index 29ffba6..4f04f65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,3 @@ -## 0.4.3 - -- working out binary release process - -## 0.4.2 - -- working out binary release process - -## 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 -- generic templates endpoint for cli -- better motd for volume mounts - -## 0.3.0 - -- created pypi release -- updated releases to use pyapp -- all new package -- port forward support -- additional_packages support - ## 0.2.0 ### Added diff --git a/justfile b/justfile index f62f5c9..8b9c260 100644 --- a/justfile +++ b/justfile @@ -3,7 +3,7 @@ delete-tag: set -euo pipefail # Get the version - VERSION=$(hatch version) + VERSION=$(cat version) # Delete the tag git tag -d "v$VERSION" @@ -14,65 +14,83 @@ delete-release: set -euo pipefail # Get the version - VERSION=$(hatch version) + VERSION=$(cat version) # Delete the release gh release delete "v$VERSION" create-tag: #!/usr/bin/env bash - VERSION=$(hatch version) + VERSION=$(cat version) git tag -a "v$VERSION" -m "Release v$VERSION" git push origin "v$VERSION" create-archives: #!/usr/bin/env bash - VERSION=$(hatch version) + VERSION=$(cat version) rm -rf dist build - hatch build -t binary - - krayt_bin=dist/binary/krayt-${VERSION} + mkdir -p dist # Create the binary for each platform for platform in "x86_64-unknown-linux-gnu" "aarch64-unknown-linux-gnu"; do - outbin="krayt-${VERSION}-${platform}" + outdir="krayt-${VERSION}-${platform}" + mkdir -p "dist/${outdir}" + # Copy the Python script and update version - cp ${krayt_bin} "dist/binary/${outbin}" + 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 .. 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 #!/usr/bin/env bash - VERSION=$(hatch version) + VERSION=$(cat version) ./scripts/get_release_notes.py "$VERSION" > release_notes.tmp - - # 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 + 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 rm release_notes.tmp preview-release-notes: #!/usr/bin/env bash - VERSION=$(hatch version) + VERSION=$(cat 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" + + diff --git a/krayt/__about__.py b/krayt/__about__.py index f6b7e26..493f741 100644 --- a/krayt/__about__.py +++ b/krayt/__about__.py @@ -1 +1 @@ -__version__ = "0.4.3" +__version__ = "0.3.0" diff --git a/krayt/cli/__init__.py b/krayt/cli/__init__.py index 035a6de..d5c6f0c 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="template", no_args_is_help=True) +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) diff --git a/krayt/cli/pod.py b/krayt/cli/pod.py index d8ac87a..6cf9aa3 100644 --- a/krayt/cli/pod.py +++ b/krayt/cli/pod.py @@ -1,6 +1,5 @@ import iterfzf from krayt.templates import env -from kubernetes.stream import stream from kubernetes import client, config import logging import os @@ -9,12 +8,6 @@ import typer from typing import Any, List, Optional import yaml from krayt.__about__ import __version__ -import sys -import tty -import termios -import select -import signal -import json logging.basicConfig(level=logging.WARNING) @@ -42,8 +35,8 @@ def format_volume_mount(vm: client.V1VolumeMount) -> dict[str, Any]: return clean_dict( { "name": vm.name, - "mount_path": vm.mount_path, - "read_only": vm.read_only if vm.read_only else None, + "mountPath": vm.mount_path, + "readOnly": vm.read_only if vm.read_only else None, } ) @@ -151,17 +144,6 @@ 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() @@ -278,81 +260,92 @@ 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) - secret_mounts = [ - client.V1VolumeMount( - name=vol.name, - mount_path=f"/mnt/secrets/{vol.secret.secret_name}", - read_only=True, + # 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, + } ) - 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) - 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 - ] + # Format mount and PVC info for MOTD + mount_info = [] + for vm in formatted_mounts: + if vm: + mount_info.append(f"{vm['name']}:{vm['mountPath']}") - template = env.get_template("base.sh") + 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 command = template.render( volumes=volumes, - pvcs=None, + pvcs=pvcs, additional_packages=additional_packages, - pre_init_scripts=None, - post_init_scripts=None, - pre_init_hooks=None, - post_init_hooks=None, + pre_init_scripts=pre_init_scripts, + post_init_scripts=post_init_scripts, + pre_init_hooks=pre_init_hooks, + post_init_hooks=post_init_hooks, ) - 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 + 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 PROTECTED_NAMESPACES = { @@ -445,164 +438,32 @@ def get_pod(namespace: Optional[str] = None): return pod_name, pod_namespace -def interactive_exec(pod_name: str, namespace: str): - # Load kubeconfig from local context (or use load_incluster_config if running inside the cluster) - 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", "-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 - 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 - try: - while resp and 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 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 Exception: - pass - - # Always restore terminal settings - termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) - print("\nConnection closed", file=sys.stderr) - - @app.command() def exec( namespace: Optional[str] = typer.Option( 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. 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 - client.CoreV1Api() pod_name, pod_namespace = get_pod(namespace) + exec_command = [ + "kubectl", + "exec", + "-it", + "-n", + pod_namespace, + pod_name, + "--", + "/bin/bash", + "-l", + ] - 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) + os.execvp("kubectl", exec_command) @app.command() @@ -779,11 +640,6 @@ 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. @@ -791,15 +647,16 @@ 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 = namespace - selected_pod = clone + selected_namespace = None + selected_pod = None 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 - get_namespaces(namespace) - pods = get_pods(namespace, label_selector="app!=krayt") - + pods = get_pods(namespace, label_selector=None) if not pods: typer.echo("No pods found.") raise typer.Exit(1) @@ -815,6 +672,9 @@ 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) @@ -834,21 +694,7 @@ def create( ) # Output the job manifest - api_client = client.ApiClient() - job_dict = api_client.sanitize_for_serialization(inspector_job) - job_yaml = yaml.dump(job_dict, sort_keys=False) - - if apply: - 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) + typer.echo(yaml.dump(clean_dict(inspector_job), sort_keys=False)) @app.command() @@ -916,10 +762,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() diff --git a/krayt/cli/templates.py b/krayt/cli/templates.py index 7416db6..841cd54 100644 --- a/krayt/cli/templates.py +++ b/krayt/cli/templates.py @@ -13,8 +13,7 @@ def list(): @app.command() -def render( - template_name: Optional[str] = typer.Option("base.sh", "--template-name", "-t"), +def base( volumes: Optional[List[str]] = typer.Option( None, "--volume", @@ -49,6 +48,7 @@ def render( 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 render( 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) diff --git a/krayt/templates/motd.sh b/krayt/templates/motd.sh index 5838161..9de1e85 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 mounts %} +{%- if volumes %} Mounted Volumes: -{%- for mount in mounts %} -- {{ mount.name }}:{{ mount.mount_path }} +{%- for volume in volumes %} +- {{ volume }} {%- endfor %} {%- endif %} diff --git a/scripts/get_release_notes.py b/scripts/get_release_notes.py index f564136..d782a15 100755 --- a/scripts/get_release_notes.py +++ b/scripts/get_release_notes.py @@ -21,11 +21,7 @@ def get_release_notes(version): You can install krayt using one of these methods: -## pypi - -``` bash -pip install krayt -``` +> !krayt requires [uv](https://docs.astral.sh/uv/getting-started/installation/) to be installed ### Using i.jpillora.com (recommended) @@ -41,8 +37,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) -- [aarch64-unknown-linux-gnu](https://github.com/waylonwalker/krayt/releases/download/v{version}/krayt-{version}-aarch64-unknown-linux-gnu)""" +- [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)""" # Get help output for main command and all subcommands try: @@ -50,23 +46,17 @@ You can also manually download the archive for your platform from the releases p # Get main help output main_help = subprocess.check_output( - ["krayt", "--help"], + ["./krayt.py", "--help"], stderr=subprocess.STDOUT, universal_newlines=True, ) help_outputs.append(("Main Command", main_help)) # Get help for each subcommand - subcommands = [ - "create", - "exec", - "clean", - "version", - "pod", - ] + subcommands = ["create", "exec", "clean", "version"] for cmd in subcommands: cmd_help = subprocess.check_output( - ["krayt", cmd, "--help"], + ["./krayt.py", cmd, "--help"], stderr=subprocess.STDOUT, universal_newlines=True, ) diff --git a/scripts/install.sh.template b/scripts/install.sh.template index 8e930c9..5fc0fb5 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/krayt/releases/download/v${RELEASE}/krayt-${RELEASE}-x86_64-unknown-linux-gnu.tar.gz" + URL="https://github.com/WaylonWalker/nvim-manager/releases/download/v${RELEASE}/nvim-manager-${RELEASE}-x86_64-unknown-linux-gnu.tar.gz" FTYPE=".tar.gz" ;; "linux_arm64") - URL="https://github.com/WaylonWalker/krayt/releases/download/v${RELEASE}/krayt-${RELEASE}-aarch64-unknown-linux-gnu.tar.gz" + URL="https://github.com/WaylonWalker/nvim-manager/releases/download/v${RELEASE}/nvim-manager-${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" >"krayt_${OS}_${ARCH}" || fail "download failed" + bash -c "$GET $URL" >"nvim-manager_${OS}_${ARCH}" || fail "download failed" else fail "unknown file type: $FTYPE" fi