Skip to content

Releases: Suchun-sv/KSTool

v2.0.1 — exec TTY + shell setup fixes

Choose a tag to compare

@Suchun-sv Suchun-sv released this 08 May 09:38

Patch release — exec TTY fixes

Thanks to @chanztuying (#3) for tracking these down.

Fixed

  • e exec on web/non-stdin terminals. execTTY now opens /dev/tty directly (matching what tcell does internally) instead of relying on os.Stdin. Previously, when KSTool was launched from a web-terminal or any context where stdin was a pipe, e would either freeze or silently fail.
  • Local terminal echo / line buffering during exec. Before invoking ExecJob, the local TTY is now switched to raw mode via term.MakeRaw. Without this, the kernel's line discipline echoed escape sequences (^[[A, bracketed-paste markers like ^[[200~) and held input until you pressed Enter. The remote shell now sees keystrokes as you type them.
  • Remote shell setup. The exec command upgraded from a bare /bin/bash to env TERM=xterm-256color /bin/sh -c 'stty sane; exec /bin/bash -i'. Two effects: readline gets a full terminfo entry (arrow keys, history search, color prompts work), and any -echo left over from a container's .bashrc is reset before the interactive shell starts.

Tooling

  • build.sh now invokes $GOROOT/bin/go instead of the ambient go binary. This avoids a silent build failure when a Go 1.25 wrapper is on PATH but the toolchain it dispatches to is older (1.22.x) and disagrees on flags.

Compatibility

Drop-in replacement for v2.0.0. No config changes. ~/.kstool/config.yaml and saved env-config presets are unchanged.

Install

wget https://github.com/Suchun-sv/KSTool/releases/download/v2.0.1/kstool-linux-amd64
chmod +x kstool-linux-amd64
./kstool-linux-amd64

Verify with SHA256SUMS if you want the integrity check.

Full diff

v2.0.0...v2.0.1

v2.0.0 — full rebuild + tier-1 UX

Choose a tag to compare

@Suchun-sv Suchun-sv released this 05 May 14:14

Highlights

KSTool v2.0.0 is a from-scratch rewrite. The two ~1000-line god-files are gone, replaced by a layered cmd/ + internal/ tree. The runtime no longer shells out to kubectl or envsubst; everything goes through client-go and a pure-Go template engine. On top of that, the daily-use surface picks up an in-TUI log viewer, a describe view, search, auto-refresh, a help overlay, and a stack of small fixes.

If you're upgrading from v1.x, your ~/.kstool/env_config_list/*.yaml presets keep working unchanged. A new ~/.kstool/config.yaml is created on first launch with the EIDF defaults you used to have hard-coded.


Rebuild

  • New layout:
    • cmd/kstool/ — wiring only.
    • internal/config/ — ~/.kstool paths, atomic 0600 writes, name allowlist.
    • internal/k8s/ — client-go wrapper (List/Get/Delete/Create/Exec/Logs/Describe).
    • internal/template/ — pure-Go ${VAR:-default} extract + render.
    • internal/tui/ — tview app, jobs / logs / describe / create / help views.
    • internal/model/, internal/editor/, internal/log/ — small focused helpers.
  • Single Kubernetes transport: client-go. kubectl and envsubst are no longer required at runtime.
  • Server-side --dry-run runs before every real Job create. Bad manifests are caught before they hit the cluster.
  • Tenancy moved into ~/.kstool/config.yaml. namespace, user_label, gpu_products, priority_classes, base_template_url, logs_tail_lines, and auto_refresh_seconds are all editable. EIDF defaults still ship out of the box.
  • All ~/.kstool writes are atomic (temp + rename) with 0600 perms. Saved-config names are validated against [A-Za-z0-9_.-]+ to block path traversal.
  • Audit log added at ~/.kstool/kstool.log (slog, structured) plus best-effort syslog. Every create / delete / exec / logs / describe action is recorded with timestamp and user.
  • Concurrency: every k8s call runs on a goroutine with a per-call timeout and posts results back via QueueUpdateDraw. The UI no longer freezes during refresh.
  • Modal / page lifecycle: real tview.Pages stack with pushPage + pop. Focus restores cleanly when modals dismiss.

New features

Log viewer (l)

  • Scrollable in-TUI pane sourced from the job's pod (Running pod preferred; falls back to most recent).
  • r re-snapshots the last logs_tail_lines lines.
  • f toggles follow mode — new lines stream in via bufio.Scanner on a goroutine.
  • / filters lines by substring; raw buffer is preserved so toggling the filter doesn't refetch.
  • q / Esc returns; the stream is cancelled and reader closed cleanly.

Describe (i)

  • A kubectl describe-style dump for the selected job.
  • Shows labels, conditions, per-pod status (with last-termination reason and exit code), and the merged event timeline (job + pod events).
  • Warning events highlighted yellow, normal events green.
  • r refreshes; q / Esc returns.

Job-list search (/)

  • Press / to reveal an input row; live-filters the table by name substring as you type.
  • Esc clears the term and returns focus to the table.
  • The active query also shows in the status bar.

Background auto-refresh

  • Configurable via auto_refresh_seconds (default 10, set to 0 to disable).
  • Throttle and refresh-in-flight indicator from the legacy code preserved.

Help overlay (?)

  • Single-key discovery for every binding across every view (job list, log viewer, describe, create flow). Closes with ? or Esc.

Terminal-resize support during exec (e)

  • New TerminalSizeQueue watches SIGWINCH and forwards the local PTY size to the remote shell. Resize your terminal, the remote tmux/vim follows. Channel-only sender so we never send-on-closed.

Bug fixes

  • ExecJob and JobLogs now share a single pickPodForJob helper. The duplicated pod-listing logic is gone.
  • Dropped textView.SetChangedFunc(Draw) in the log view — QueueUpdateDraw already triggers a redraw, the extra hook caused jittery double-draws.
  • execTTY no longer blocks on fmt.Scanln after an exec error. Errors surface in a normal modal once the TUI is back.
  • The legacy ${VAR:-default} regex couldn't handle nested braces or } inside defaults. The new pure-Go scanner tracks brace depth correctly. Bash variables without :- (e.g. $pid, $! in container args) are left untouched.
  • Saved-preset names are validated. name=../evil is rejected before it reaches the filesystem.
  • ~/.kstool/*.yaml writes are atomic and 0600. Concurrent KSTool instances no longer clobber each other's state.
  • HTTP fetch of the default template has a 10 s timeout. A slow network can't block startup forever.
  • Migrated logging from log/syslog to log/slog for structured records on disk; syslog is still attempted best-effort.

Tooling

  • build.sh does a stripped (-s -w) static build and an atomic remote deploy: scps as kstool.new, then mv swaps the directory entry. A kstool already running on the remote keeps its old inode (no Text file busy) and exits cleanly when the user quits.
  • .gitignore no longer accidentally ignores go.mod / go.sum. The built binary /kstool is correctly ignored.
  • README rewritten end-to-end for the v2 layout.

Removed

  • main.go (1145 lines) and src/ (946 lines) — replaced by the cmd/ + internal/ tree.
  • The envsubst runtime dependency.
  • The kubectl runtime dependency for create / exec / logs.
  • The hard-coded EIDF tenancy constants — moved to config.

Verification

  • go vet ./..., go build ./cmd/kstool, go test ./... all clean.
  • internal/template carries the unit-test coverage; the engine is regression-tested for nested defaults, environment override, plain shell preservation, and unknown shapes.
  • TUI and k8s layers were exercised by hand against an EIDF cluster.

Install

Pre-built static binaries are attached. Verify with SHA256SUMS:

wget https://github.com/Suchun-sv/KSTool/releases/download/v2.0.0/kstool-linux-amd64
chmod +x kstool-linux-amd64
./kstool-linux-amd64

Or build from source:

git clone https://github.com/Suchun-sv/KSTool.git
cd KSTool
go build -o kstool ./cmd/kstool

Full diff

53f8af3...v2.0.0

Support creating new configuration

Pre-release

Choose a tag to compare

@Suchun-sv Suchun-sv released this 23 Apr 10:50

We now support the new configuration feature 🎉🎉🎉

  1. In your configure.yaml, use placeholders in the form of ${ENV_NAME:-DEFAULT_VALUE} (note the syntax: :-, not just :), see config/examples/* for example.
  2. Upload your updated configure.yaml to ~/.kstool/base_apply.yaml. Please ensure the file path and name are correct.
  3. Launch kstool, and press n to create a new configuration file.

Other changes:

Update Log

  1. Job Execution and Deletion Permissions:

    • Implemented a mechanism to determine job execution and deletion permissions using the eidf/user label. This ensures that only the owner of a job, as specified by this label, can execute or delete it.
  2. Priority Class Configuration:

    • Added the priority-class label to the default YAML configuration.
    • Integrated a dropdown list in the job creation form to allow users to select the desired priority class.
  3. NFS Path and Task Script Configuration:

    • Updated the default NFS path to "/user/USER_NAME/" -> "/workspace"
    • Modified the default command to use the $TASK_SCRIPT variable, guiding users to specify their task scripts in the /workspace dir rather than writing command in the yaml.
  4. Add New function of (C)onfig to see each job's configuration
    Simply write the config to a temp yaml file, and use vim (Read-only) to read them.

  5. Signal Handling in Default Command:

    • Enhanced the default command configuration to include a trap for the kill 1 signal. This improvement allows jobs to handle termination signals gracefully. However, the updated job status is "failed" rather than "complete“ when terminated. It wouldn't affect use, but I don't know why.
  6. Logging Enhancements:

    • Integrated logging functionality using the log/syslog package to record three job-related events: (E)nter job; (D)elete job; (N)ewconfig. The (N)ew config only be recorded when applying the new job. However, I cannot access to the system-level log, so I didn't chek&debug, which may still ask for manager's kind help.

v1.0.1 Release

Choose a tag to compare

@Suchun-sv Suchun-sv released this 22 Apr 21:41

Version 1.0.1 🎉🎉

TODO:

  1. Change the logic of (N)ew config that may suitable for everyone.