Repository navigation
Releases: Suchun-sv/KSTool
Release list
v2.0.1 — exec TTY + shell setup fixes
Patch release — exec TTY fixes
Thanks to @chanztuying (#3) for tracking these down.
Fixed
eexec on web/non-stdin terminals.execTTYnow opens/dev/ttydirectly (matching whattcelldoes internally) instead of relying onos.Stdin. Previously, when KSTool was launched from a web-terminal or any context where stdin was a pipe,ewould either freeze or silently fail.- Local terminal echo / line buffering during exec. Before invoking
ExecJob, the local TTY is now switched to raw mode viaterm.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/bashtoenv 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-echoleft over from a container's.bashrcis reset before the interactive shell starts.
Tooling
build.shnow invokes$GOROOT/bin/goinstead of the ambientgobinary. This avoids a silent build failure when a Go 1.25 wrapper is onPATHbut 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-amd64Verify with SHA256SUMS if you want the integrity check.
Full diff
v2.0.0 — full rebuild + tier-1 UX
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/—~/.kstoolpaths, atomic 0600 writes, name allowlist.internal/k8s/—client-gowrapper (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.kubectlandenvsubstare no longer required at runtime. - Server-side
--dry-runruns before every realJobcreate. 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, andauto_refresh_secondsare all editable. EIDF defaults still ship out of the box. - All
~/.kstoolwrites are atomic (temp + rename) with0600perms. 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.Pagesstack withpushPage+ 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).
rre-snapshots the lastlogs_tail_lineslines.ftoggles follow mode — new lines stream in viabufio.Scanneron a goroutine./filters lines by substring; raw buffer is preserved so toggling the filter doesn't refetch.q/Escreturns; 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.
rrefreshes;q/Escreturns.
Job-list search (/)
- Press
/to reveal an input row; live-filters the table by name substring as you type. Escclears 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(default10, set to0to 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
?orEsc.
Terminal-resize support during exec (e)
- New
TerminalSizeQueuewatchesSIGWINCHand forwards the local PTY size to the remote shell. Resize your terminal, the remotetmux/vimfollows. Channel-only sender so we never send-on-closed.
Bug fixes
ExecJobandJobLogsnow share a singlepickPodForJobhelper. The duplicated pod-listing logic is gone.- Dropped
textView.SetChangedFunc(Draw)in the log view —QueueUpdateDrawalready triggers a redraw, the extra hook caused jittery double-draws. execTTYno longer blocks onfmt.Scanlnafter 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=../evilis rejected before it reaches the filesystem. ~/.kstool/*.yamlwrites are atomic and0600. 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/syslogtolog/slogfor structured records on disk; syslog is still attempted best-effort.
Tooling
build.shdoes a stripped (-s -w) static build and an atomic remote deploy:scps askstool.new, thenmvswaps the directory entry. Akstoolalready running on the remote keeps its old inode (noText file busy) and exits cleanly when the user quits..gitignoreno longer accidentally ignoresgo.mod/go.sum. The built binary/kstoolis correctly ignored.- README rewritten end-to-end for the v2 layout.
Removed
main.go(1145 lines) andsrc/(946 lines) — replaced by thecmd/+internal/tree.- The
envsubstruntime dependency. - The
kubectlruntime 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/templatecarries 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-amd64Or build from source:
git clone https://github.com/Suchun-sv/KSTool.git
cd KSTool
go build -o kstool ./cmd/kstoolFull diff
53f8af3...v2.0.0
Support creating new configuration
We now support the new configuration feature 🎉🎉🎉
- In your configure.yaml, use placeholders in the form of ${ENV_NAME:-DEFAULT_VALUE} (note the syntax: :-, not just :), see
config/examples/*for example. - Upload your updated configure.yaml to
~/.kstool/base_apply.yaml. Please ensure the file path and name are correct. - Launch kstool, and press
nto create a new configuration file.
Other changes:
Update Log
-
Job Execution and Deletion Permissions:
- Implemented a mechanism to determine job execution and deletion permissions using the
eidf/userlabel. This ensures that only the owner of a job, as specified by this label, can execute or delete it.
- Implemented a mechanism to determine job execution and deletion permissions using the
-
Priority Class Configuration:
- Added the
priority-classlabel to the default YAML configuration. - Integrated a dropdown list in the job creation form to allow users to select the desired priority class.
- Added the
-
NFS Path and Task Script Configuration:
- Updated the default NFS path to "/user/USER_NAME/" -> "/workspace"
- Modified the default command to use the
$TASK_SCRIPTvariable, guiding users to specify their task scripts in the /workspace dir rather than writing command in the yaml.
-
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. -
Signal Handling in Default Command:
- Enhanced the default command configuration to include a trap for the
kill 1signal. 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.
- Enhanced the default command configuration to include a trap for the
-
Logging Enhancements:
- Integrated logging functionality using the
log/syslogpackage 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.
- Integrated logging functionality using the
v1.0.1 Release
Version 1.0.1 🎉🎉
TODO:
- Change the logic of (N)ew config that may suitable for everyone.