KubeRich
Browse documentation

GET STARTED

Local preferences and diagnostics

KubeRich provides info, config init, config check, config migrate, and local diagnostic logging, alongside the resource workspace. Preference inspection does not connect to Kubernetes. The UI applies built-in themes and displays read-only mode in both header/status and shared command decisions. The native shell service applies the shared read-only guard before preparation.

Legacy preview compatibility

KubeRich uses kuberich for its package, Python imports and canonical command. The kubetrol console command remains an alias to the same entry point for the initial preview. Its help/version identify KubeRich. The old Python module and distribution are not duplicate packages; use python -m kuberich for module launch. Removing the alias requires a later minor release and migration notes.

Default preference selection is CLI --config, then KUBERICH_CONFIG, then KUBETROL_CONFIG, then the platform's KubeRich file. If no KubeRich file exists, the old platform Kubetrol config.yaml is read in place. An existing or broken symlink/directory/invalid KubeRich file never silently falls back to old settings. Each KUBERICH_* preference variable wins over its corresponding KUBETROL_* alias; CLI overrides still have highest precedence. Explicit files never fall back to another location. Environment-provided relative log paths retain the launch directory rather than the preference directory.

info reports the file actually read, whether migration is pending and the new target, without writing either file. config check and ordinary loading also leave preferences unchanged. config init refuses to replace existing legacy preferences. Use config migrate with default paths and without runtime overrides to create a mode-0600 KubeRich file atomically. It retains the original, unknown fields, read-only policy and effective settings; relative file-provided log destinations are made absolute to preserve their target. Existing legacy log/lock headers and archives remain accepted for explicitly configured log destinations. Default new logs use KubeRich's new platform directory.

An existing destination is never replaced, including a competing creation during the commit. Repeating a completed migration validates the current file and makes no change. Explicit --config or configuration environment paths cannot be relocated implicitly by this command. It does not move kubeconfig, credentials, diagnostic logs or tool installations.

Commands

uv run kuberich info
uv run kuberich config check
uv run kuberich config init
uv run kuberich config migrate
uv run kuberich --config /path/to/preferences.yaml config check
uv run kuberich --log-level DEBUG --log-file /path/to/kuberich.log

Place global flags before a command. --logLevel/-l and --logFile are aliases for --log-level and --log-file. --config selects KubeRich preferences; --kubeconfig selects Kubernetes connection configuration for a terminal launch.

info prints JSON with installed versions, local config/data/log paths, validated effective preferences, unknown-field count and migration status. It never prints unknown field names/values, credential environment variables or kubeconfig contents. info and config check create no files. They do not execute cloud credential helpers or inspect/connect to a cluster.

config init creates schema-v1 defaults at the selected path. It never overwrites an existing file, persists environment overrides, or creates diagnostic logs. All runtime overrides are rejected for this command. You can edit the YAML with your own editor and run config check afterward. There is no automatic rewrite on load.

Paths and precedence

The config path is chosen from --config, then KUBERICH_CONFIG, then KUBETROL_CONFIG, then the platform default with the legacy fallback described above. Defaults follow platformdirs. An absent default file uses the defaults below. An explicitly selected missing file fails with exit 3; use config init to create it. Empty/comment-only files also use defaults. Paths expand ~, support spaces and reject control characters.

Platform Default preferences Default diagnostic log
Linux $XDG_CONFIG_HOME/kuberich/config.yaml or ~/.config/kuberich/config.yaml $XDG_STATE_HOME/kuberich/log/kuberich.log or ~/.local/state/kuberich/log/kuberich.log
macOS ~/Library/Application Support/kuberich/config.yaml ~/Library/Logs/kuberich/kuberich.log

info reports the actual paths on your machine. Preference operations never load Kubernetes credentials or change kubeconfig or its current-context. Files recognized as kubeconfig are rejected as preferences. Startup never writes preference files.

Preference precedence is explicit runtime CLI override → KUBERICH_* environment → selected YAML → defaults. Each layer is validated; a malformed file/environment value fails even if a higher layer would override it. This prevents an invalid lower layer from silently resurfacing on the next invocation. The file is always read; log flags do not bypass a broken config.

YAML field Default Environment Runtime CLI
shell ["sh"] Not available Not available; configure YAML
theme k9s KUBERICH_THEME Not yet available
refresh_seconds 2.0 KUBERICH_REFRESH --refresh, -r; periodic table ages/local repaint, independent of live watches
read_only false KUBERICH_READONLY --readonly / --write (mutually exclusive)
log_level WARNING KUBERICH_LOG_LEVEL --log-level, --logLevel, -l
log_file null (platform path) KUBERICH_LOG_FILE --log-file, --logFile

Environment read-only values are true/false, case insensitive. Levels accept DEBUG, INFO, WARNING, ERROR or CRITICAL, case insensitive, and are normalized to uppercase in effective settings. Refresh must be a finite number in 0.1–3600 seconds; booleans and numeric strings in YAML are rejected. Theme IDs are 1–64 ASCII letters/digits/underscores/hyphens starting with a letter; available themes must also be k9s or registered built-in Textual themes when opening the UI. config check validates the schema, while the UI validates availability. A null log path selects the platform default, while an empty path is an error.

Relative log_file values from YAML resolve against that file's directory. Relative environment/CLI paths resolve against the invocation's working directory, including when their text happens to match the file's value.

Runtime choices never rewrite preferences. --write explicitly overrides a valid file/environment read-only setting for this invocation. Read-only blocks commands through a shared service decision, including the native shell service. See the launch contract for aliases, availability and command-specific option handling. Context-specific preference precedence arrives with context support; the current flat schema applies global settings only.

shell is a list of 1–32 nonempty strings, with an executable first and literal arguments after it. Strings and shell expressions are rejected. For example, shell: ["/bin/bash", "-l"] selects bash only in images that contain it. The list is captured at launch; restart after changing it. Diagnostics omit this argument list. See native shells.

Schema, compatibility and writes

schema_version: 1
theme: textual-dark
refresh_seconds: 2.0
read_only: false
log_level: WARNING
log_file: null
shell: ["sh"]

Unknown fields are retained in memory and preserved by the atomic save API; they do not become effective settings or appear in diagnostics. Unknown schema versions are rejected so older builds cannot overwrite a newer schema. Versionless/v0 preferences migrate refresh to refresh_seconds and readonly to read_only in memory. Supplying both a legacy and current name fails. A later explicit save writes version 1 while retaining unknown fields; current CLI commands do not perform that migration write automatically.

YAML uses a safe loader, unique string keys and a 64 KiB input limit. Aliases, object-construction tags, multiple documents, more than 20 nested collections and excessive parser events are rejected. Parser errors identify the problem without echoing source values or source excerpts.

Writes use a mode-0600 temporary file in the destination directory, flush/fsync it, and commit with an atomic link for creation or replace for an explicit save. Creation cannot overwrite a concurrent writer. New application directories are mode 0700; existing parent directories keep their permissions. Destination symlinks are refused. A failure or interrupt before commit leaves the previous file intact and removes the temporary file. A post-commit cleanup/directory-sync failure returns exit 3 and explicitly says the preferences were saved but durability or cleanup could not be confirmed; reread the file before retrying.

Logging and errors

The ordinary CLI creates its local log and a small persistent .lock sibling, both mode 0600. A nonblocking process lock permits only one writer per log path; concurrent instances must use different --log-file values. Logs rotate at approximately 1 MiB with three archives. Each formatted record is bounded to 8 KiB in UTF-8; total log storage is bounded by four times (1 MiB + 8 KiB), plus the small lock file. Open files and locks are released on normal exit or failure.

Nonempty destinations and existing archives must have KubeRich's diagnostic header. Foreign files, symlinks and nonregular files are refused rather than modified. This includes a mistakenly selected kubeconfig. An empty regular file is accepted. These checks prevent mistaken destinations; they are not a sandbox against another program modifying files with the same user's privileges.

Logs use an application-owned logger without console handlers or root/SDK logging configuration changes. Messages redact common tokens, Bearer/Basic auth, JWTs, passwords, secret/access/API keys, private-key blocks, certificate data and HTTP URL passwords. Terminal control and directional-control characters are escaped. Debug exceptions include type and frame locations, excluding exception values, source text, chained exception values and locals. Raw kubeconfig, external command output, credential-helper responses and arbitrary API bodies must never be logged; pattern matching is defense in depth, not proof that arbitrary text contains no secret. Debug output stays in the file.

Exit Meaning
0 Successful command, help, version or normal UI quit (including Ctrl+C)
1 Unexpected internal/local failure; concise message without raw exception
2 Invalid arguments, settings, schema, YAML or a noninteractive UI launch
3 Missing explicit file, local permissions/I/O, existing init destination or log ownership failure
4 Recognized option/command requires behavior not shipped in this version
130 Interrupted non-UI operation
143 SIGTERM during a native shell, after cleanup and terminal restoration

Argument parsing does not echo rejected arguments, which might contain tokens. Settings errors name the setting without printing its value. Logging failures cannot fall back to Python logging's raw-record stderr output.

The tests exercise temporary files, real wheel entry points, injected permission, replace/fsync failures, interrupts, migration round trips, redaction, bounded rotation and an actual second process competing for a log. They never use a real cluster or the maintainer's kubeconfig.