Repository navigation
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