kdebug 0.2.2__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kdebug-0.2.2 → kdebug-0.3.0}/PKG-INFO +2 -2
- {kdebug-0.2.2 → kdebug-0.3.0}/pyproject.toml +12 -2
- {kdebug-0.2.2 → kdebug-0.3.0}/src/kdebug/cli.py +47 -266
- kdebug-0.3.0/src/kdebug/completions/__init__.py +0 -0
- {kdebug-0.2.2 → kdebug-0.3.0/src/kdebug}/completions/_kdebug +35 -16
- {kdebug-0.2.2 → kdebug-0.3.0/src/kdebug}/completions/kdebug.bash +17 -30
- kdebug-0.3.0/src/kdebug/completions/kdebug.fish +121 -0
- kdebug-0.2.2/.github/dependabot.yml +0 -10
- kdebug-0.2.2/.github/workflows/pypi-publish.yml +0 -40
- kdebug-0.2.2/.github/workflows/release.yml +0 -87
- kdebug-0.2.2/.github/workflows/update-homebrew.yml +0 -37
- kdebug-0.2.2/AGENTS.md +0 -163
- kdebug-0.2.2/uv.lock +0 -8
- {kdebug-0.2.2 → kdebug-0.3.0}/.gitignore +0 -0
- {kdebug-0.2.2 → kdebug-0.3.0}/README.md +0 -0
- {kdebug-0.2.2 → kdebug-0.3.0}/src/kdebug/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kdebug
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Universal Kubernetes Debug Container Utility
|
|
5
5
|
Project-URL: Homepage, https://github.com/jessegoodier/kdebug
|
|
6
6
|
Project-URL: Repository, https://github.com/jessegoodier/kdebug
|
|
@@ -13,7 +13,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
13
13
|
Classifier: Operating System :: MacOS
|
|
14
14
|
Classifier: Operating System :: POSIX :: Linux
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
|
-
Requires-Python: >=3.
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
|
|
19
19
|
# kdebug - Universal Kubernetes Debug and File Copy Container Utility
|
|
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "kdebug"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Universal Kubernetes Debug Container Utility"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
12
|
authors = [{ name = "Jesse Goodier" }]
|
|
13
13
|
keywords = ["kubernetes", "debug", "kubectl", "cli"]
|
|
14
14
|
classifiers = [
|
|
@@ -23,6 +23,16 @@ classifiers = [
|
|
|
23
23
|
[project.scripts]
|
|
24
24
|
kdebug = "kdebug.cli:main"
|
|
25
25
|
|
|
26
|
+
[tool.hatch.build]
|
|
27
|
+
include = ["src/kdebug"]
|
|
28
|
+
|
|
29
|
+
[tool.hatch.build.targets.wheel]
|
|
30
|
+
packages = ["src/kdebug"]
|
|
31
|
+
artifacts = ["src/kdebug/completions/*"]
|
|
32
|
+
|
|
33
|
+
[tool.hatch.build.targets.sdist]
|
|
34
|
+
include = ["src/kdebug"]
|
|
35
|
+
|
|
26
36
|
[project.urls]
|
|
27
37
|
Homepage = "https://github.com/jessegoodier/kdebug"
|
|
28
38
|
Repository = "https://github.com/jessegoodier/kdebug"
|
|
@@ -8,7 +8,7 @@ interactive shell access and backup capabilities.
|
|
|
8
8
|
|
|
9
9
|
Usage Examples:
|
|
10
10
|
# Interactive session with controller
|
|
11
|
-
./kdebug.py -n kubecost --controller sts
|
|
11
|
+
./kdebug.py -n kubecost --controller sts/aggregator --container aggregator --cmd bash
|
|
12
12
|
|
|
13
13
|
# Interactive session with direct pod
|
|
14
14
|
./kdebug.py -n kubecost --pod aggregator-0 --container aggregator
|
|
@@ -17,10 +17,11 @@ Usage Examples:
|
|
|
17
17
|
./kdebug.py -n kubecost --pod aggregator-0 --container aggregator --backup /var/configs
|
|
18
18
|
|
|
19
19
|
# Using deployment
|
|
20
|
-
./kdebug.py -n myapp --controller
|
|
20
|
+
./kdebug.py -n myapp --controller deploy/frontend --cmd sh
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
import argparse
|
|
24
|
+
import importlib.resources
|
|
24
25
|
import json
|
|
25
26
|
import os
|
|
26
27
|
import subprocess
|
|
@@ -455,18 +456,12 @@ def select_pod(args) -> Optional[Dict]:
|
|
|
455
456
|
|
|
456
457
|
# Controller-based selection
|
|
457
458
|
if args.controller:
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
"Error: --controller-name is required when using --controller",
|
|
461
|
-
file=sys.stderr,
|
|
462
|
-
)
|
|
463
|
-
return None
|
|
464
|
-
|
|
465
|
-
pods = get_pods_by_controller(args.controller, args.controller_name, namespace)
|
|
459
|
+
controller_type, controller_name = args.controller
|
|
460
|
+
pods = get_pods_by_controller(controller_type, controller_name, namespace)
|
|
466
461
|
|
|
467
462
|
if not pods:
|
|
468
463
|
print(
|
|
469
|
-
f"No pods found for {
|
|
464
|
+
f"No pods found for {controller_type} '{controller_name}'",
|
|
470
465
|
file=sys.stderr,
|
|
471
466
|
)
|
|
472
467
|
return None
|
|
@@ -998,246 +993,43 @@ def cleanup_debug_container(
|
|
|
998
993
|
return True
|
|
999
994
|
|
|
1000
995
|
|
|
1001
|
-
def
|
|
1002
|
-
"""
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
_kdebug_get_contexts() {
|
|
1010
|
-
kubectl config get-contexts -o name 2>/dev/null
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
_kdebug_get_namespaces() {
|
|
1014
|
-
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
1015
|
-
kubectl $kubectl_args get namespaces -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
_kdebug_get_pods() {
|
|
1019
|
-
local ns="${1:-default}"
|
|
1020
|
-
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
1021
|
-
kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
|
-
_kdebug_get_controllers() {
|
|
1025
|
-
local ns="${1:-default}"
|
|
1026
|
-
local controller_type="$2"
|
|
1027
|
-
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
1028
|
-
case "$controller_type" in
|
|
1029
|
-
deployment|deploy)
|
|
1030
|
-
kubectl $kubectl_args get deployments -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
1031
|
-
;;
|
|
1032
|
-
statefulset|sts)
|
|
1033
|
-
kubectl $kubectl_args get statefulsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
1034
|
-
;;
|
|
1035
|
-
daemonset|ds)
|
|
1036
|
-
kubectl $kubectl_args get daemonsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
1037
|
-
;;
|
|
1038
|
-
esac
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
_kdebug_get_kubectl_args() {
|
|
1042
|
-
local i args=""
|
|
1043
|
-
for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
|
|
1044
|
-
case "${COMP_WORDS[i]}" in
|
|
1045
|
-
--context)
|
|
1046
|
-
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
1047
|
-
args="$args --context=${COMP_WORDS[$((i+1))]}"
|
|
1048
|
-
fi
|
|
1049
|
-
;;
|
|
1050
|
-
--context=*)
|
|
1051
|
-
args="$args ${COMP_WORDS[i]}"
|
|
1052
|
-
;;
|
|
1053
|
-
--kubeconfig)
|
|
1054
|
-
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
1055
|
-
args="$args --kubeconfig=${COMP_WORDS[$((i+1))]}"
|
|
1056
|
-
fi
|
|
1057
|
-
;;
|
|
1058
|
-
--kubeconfig=*)
|
|
1059
|
-
args="$args ${COMP_WORDS[i]}"
|
|
1060
|
-
;;
|
|
1061
|
-
esac
|
|
1062
|
-
done
|
|
1063
|
-
echo "$args"
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
_kdebug_get_namespace_from_args() {
|
|
1067
|
-
local i
|
|
1068
|
-
for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
|
|
1069
|
-
case "${COMP_WORDS[i]}" in
|
|
1070
|
-
-n|--namespace)
|
|
1071
|
-
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
1072
|
-
echo "${COMP_WORDS[$((i+1))]}"
|
|
1073
|
-
return
|
|
1074
|
-
fi
|
|
1075
|
-
;;
|
|
1076
|
-
-n=*|--namespace=*)
|
|
1077
|
-
echo "${COMP_WORDS[i]#*=}"
|
|
1078
|
-
return
|
|
1079
|
-
;;
|
|
1080
|
-
esac
|
|
1081
|
-
done
|
|
1082
|
-
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
1083
|
-
kubectl $kubectl_args config view --minify -o jsonpath='{..namespace}' 2>/dev/null || echo "default"
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
_kdebug_get_controller_from_args() {
|
|
1087
|
-
local i
|
|
1088
|
-
for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
|
|
1089
|
-
case "${COMP_WORDS[i]}" in
|
|
1090
|
-
--controller)
|
|
1091
|
-
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
1092
|
-
echo "${COMP_WORDS[$((i+1))]}"
|
|
1093
|
-
return
|
|
1094
|
-
fi
|
|
1095
|
-
;;
|
|
1096
|
-
--controller=*)
|
|
1097
|
-
echo "${COMP_WORDS[i]#*=}"
|
|
1098
|
-
return
|
|
1099
|
-
;;
|
|
1100
|
-
esac
|
|
1101
|
-
done
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
_kdebug() {
|
|
1105
|
-
local cur prev words cword
|
|
1106
|
-
_init_completion || return
|
|
1107
|
-
|
|
1108
|
-
local opts="--pod --controller --controller-name -n --namespace --context --kubeconfig
|
|
1109
|
-
--container --debug-image --cmd --cd-into --backup --compress --as-root
|
|
1110
|
-
--debug --completions -V --version --help -h"
|
|
1111
|
-
|
|
1112
|
-
local controller_types="deployment deploy statefulset sts daemonset ds"
|
|
1113
|
-
|
|
1114
|
-
case "$prev" in
|
|
1115
|
-
-n|--namespace)
|
|
1116
|
-
COMPREPLY=($(compgen -W "$(_kdebug_get_namespaces)" -- "$cur"))
|
|
1117
|
-
return
|
|
1118
|
-
;;
|
|
1119
|
-
--context)
|
|
1120
|
-
COMPREPLY=($(compgen -W "$(_kdebug_get_contexts)" -- "$cur"))
|
|
1121
|
-
return
|
|
1122
|
-
;;
|
|
1123
|
-
--kubeconfig)
|
|
1124
|
-
_filedir
|
|
1125
|
-
return
|
|
1126
|
-
;;
|
|
1127
|
-
--pod)
|
|
1128
|
-
local ns=$(_kdebug_get_namespace_from_args)
|
|
1129
|
-
COMPREPLY=($(compgen -W "$(_kdebug_get_pods "$ns")" -- "$cur"))
|
|
1130
|
-
return
|
|
1131
|
-
;;
|
|
1132
|
-
--controller)
|
|
1133
|
-
COMPREPLY=($(compgen -W "$controller_types" -- "$cur"))
|
|
1134
|
-
return
|
|
1135
|
-
;;
|
|
1136
|
-
--controller-name)
|
|
1137
|
-
local ns=$(_kdebug_get_namespace_from_args)
|
|
1138
|
-
local ct=$(_kdebug_get_controller_from_args)
|
|
1139
|
-
if [[ -n "$ct" ]]; then
|
|
1140
|
-
COMPREPLY=($(compgen -W "$(_kdebug_get_controllers "$ns" "$ct")" -- "$cur"))
|
|
1141
|
-
fi
|
|
1142
|
-
return
|
|
1143
|
-
;;
|
|
1144
|
-
--container|--debug-image|--cmd|--cd-into|--backup)
|
|
1145
|
-
# These take arbitrary values, no completion
|
|
1146
|
-
return
|
|
1147
|
-
;;
|
|
1148
|
-
--completions)
|
|
1149
|
-
COMPREPLY=($(compgen -W "bash zsh" -- "$cur"))
|
|
1150
|
-
return
|
|
1151
|
-
;;
|
|
1152
|
-
esac
|
|
1153
|
-
|
|
1154
|
-
if [[ "$cur" == -* ]]; then
|
|
1155
|
-
COMPREPLY=($(compgen -W "$opts" -- "$cur"))
|
|
1156
|
-
return
|
|
1157
|
-
fi
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
complete -F _kdebug kdebug
|
|
1161
|
-
"""
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
def generate_zsh_completion() -> str:
|
|
1165
|
-
"""Generate zsh completion script."""
|
|
1166
|
-
return """#compdef kdebug
|
|
1167
|
-
# kdebug zsh completion
|
|
1168
|
-
# Install: kdebug --completions zsh > ~/.zsh/completions/_kdebug
|
|
1169
|
-
# Or: source <(kdebug --completions zsh)
|
|
1170
|
-
|
|
1171
|
-
_kdebug_kubectl_args() {
|
|
1172
|
-
local args=""
|
|
1173
|
-
[[ -n "${opt_args[--context]}" ]] && args="$args --context=${opt_args[--context]}"
|
|
1174
|
-
[[ -n "${opt_args[--kubeconfig]}" ]] && args="$args --kubeconfig=${opt_args[--kubeconfig]}"
|
|
1175
|
-
echo "$args"
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
_kdebug_contexts() {
|
|
1179
|
-
local -a contexts
|
|
1180
|
-
contexts=(${(f)"$(kubectl config get-contexts -o name 2>/dev/null)"})
|
|
1181
|
-
_describe 'context' contexts
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
_kdebug_namespaces() {
|
|
1185
|
-
local kubectl_args=$(_kdebug_kubectl_args)
|
|
1186
|
-
local -a namespaces
|
|
1187
|
-
namespaces=(${(f)"$(kubectl $kubectl_args get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\\n"}{end}' 2>/dev/null)"})
|
|
1188
|
-
_describe 'namespace' namespaces
|
|
1189
|
-
}
|
|
996
|
+
def _output_completion_script(shell: str) -> None:
|
|
997
|
+
"""Output the shell completion script and exit."""
|
|
998
|
+
files = {"bash": "kdebug.bash", "zsh": "_kdebug", "fish": "kdebug.fish"}
|
|
999
|
+
filename = files.get(shell)
|
|
1000
|
+
if not filename:
|
|
1001
|
+
print(f"Unknown shell: {shell}", file=sys.stderr)
|
|
1002
|
+
sys.exit(1)
|
|
1190
1003
|
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1004
|
+
try:
|
|
1005
|
+
completions_pkg = importlib.resources.files("kdebug.completions")
|
|
1006
|
+
script = (completions_pkg / filename).read_text()
|
|
1007
|
+
print(script)
|
|
1008
|
+
except Exception as e:
|
|
1009
|
+
print(f"Error reading completion script: {e}", file=sys.stderr)
|
|
1010
|
+
sys.exit(1)
|
|
1198
1011
|
|
|
1199
|
-
_kdebug_controller_names() {
|
|
1200
|
-
local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
|
|
1201
|
-
local ct="${opt_args[--controller]:-deployment}"
|
|
1202
|
-
local kubectl_args=$(_kdebug_kubectl_args)
|
|
1203
|
-
local resource
|
|
1204
|
-
case "$ct" in
|
|
1205
|
-
deployment|deploy) resource="deployments" ;;
|
|
1206
|
-
statefulset|sts) resource="statefulsets" ;;
|
|
1207
|
-
daemonset|ds) resource="daemonsets" ;;
|
|
1208
|
-
*) resource="deployments" ;;
|
|
1209
|
-
esac
|
|
1210
|
-
local -a names
|
|
1211
|
-
names=(${(f)"$(kubectl $kubectl_args get "$resource" -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\\n"}{end}' 2>/dev/null)"})
|
|
1212
|
-
_describe 'controller name' names
|
|
1213
|
-
}
|
|
1214
1012
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
args=(
|
|
1218
|
-
'(-V --version)'{-V,--version}'[Show version and exit]'
|
|
1219
|
-
'(-h --help)'{-h,--help}'[Show help message]'
|
|
1220
|
-
'--pod[Pod name for direct selection]:pod:_kdebug_pods'
|
|
1221
|
-
'--controller[Controller type]:type:(deployment deploy statefulset sts daemonset ds)'
|
|
1222
|
-
'--controller-name[Controller name]:name:_kdebug_controller_names'
|
|
1223
|
-
'(-n --namespace)'{-n,--namespace}'[Kubernetes namespace]:namespace:_kdebug_namespaces'
|
|
1224
|
-
'--context[Kubernetes context to use]:context:_kdebug_contexts'
|
|
1225
|
-
'--kubeconfig[Path to kubeconfig file]:path:_files'
|
|
1226
|
-
'--container[Target container for process namespace sharing]:container:'
|
|
1227
|
-
'--debug-image[Debug container image]:image:'
|
|
1228
|
-
'--cmd[Command to run in debug container]:command:'
|
|
1229
|
-
'--cd-into[Change to directory on start]:directory:_files -/'
|
|
1230
|
-
'--backup[Copy path from pod to local backups]:path:'
|
|
1231
|
-
'--compress[Compress backup as tar.gz]'
|
|
1232
|
-
'--as-root[Run debug container as root]'
|
|
1233
|
-
'--debug[Show kubectl commands being executed]'
|
|
1234
|
-
'--completions[Output shell completion script]:shell:(bash zsh)'
|
|
1235
|
-
)
|
|
1236
|
-
_arguments -s $args
|
|
1237
|
-
}
|
|
1013
|
+
def parse_controller_arg(value: str) -> Tuple[str, str]:
|
|
1014
|
+
"""Parse --controller TYPE/NAME format and return (controller_type, controller_name).
|
|
1238
1015
|
|
|
1239
|
-
|
|
1240
|
-
"""
|
|
1016
|
+
Raises argparse.ArgumentTypeError on invalid input.
|
|
1017
|
+
"""
|
|
1018
|
+
if "/" not in value:
|
|
1019
|
+
raise argparse.ArgumentTypeError(
|
|
1020
|
+
f"Invalid format '{value}'. Expected TYPE/NAME (e.g. sts/myapp, deploy/frontend)."
|
|
1021
|
+
)
|
|
1022
|
+
controller_type, controller_name = value.split("/", 1)
|
|
1023
|
+
if not controller_name:
|
|
1024
|
+
raise argparse.ArgumentTypeError(
|
|
1025
|
+
f"Missing controller name after '/'. Expected TYPE/NAME (e.g. sts/myapp)."
|
|
1026
|
+
)
|
|
1027
|
+
if controller_type.lower() not in CONTROLLER_ALIASES:
|
|
1028
|
+
valid_types = ", ".join(sorted(CONTROLLER_ALIASES.keys()))
|
|
1029
|
+
raise argparse.ArgumentTypeError(
|
|
1030
|
+
f"Unknown controller type '{controller_type}'. Valid types: {valid_types}"
|
|
1031
|
+
)
|
|
1032
|
+
return (controller_type, controller_name)
|
|
1241
1033
|
|
|
1242
1034
|
|
|
1243
1035
|
class KdebugHelpFormatter(argparse.RawDescriptionHelpFormatter):
|
|
@@ -1258,12 +1050,13 @@ def main():
|
|
|
1258
1050
|
Usage:
|
|
1259
1051
|
kdebug [options] Interactive TUI mode
|
|
1260
1052
|
kdebug --pod POD [options] Direct pod selection
|
|
1261
|
-
kdebug --controller TYPE
|
|
1053
|
+
kdebug --controller TYPE/NAME [options] Controller selection""",
|
|
1262
1054
|
formatter_class=KdebugHelpFormatter,
|
|
1263
1055
|
epilog="""Examples:
|
|
1264
1056
|
kdebug # Interactive TUI
|
|
1265
1057
|
kdebug -n prod --pod api-0 # Direct pod
|
|
1266
|
-
kdebug --controller sts
|
|
1058
|
+
kdebug --controller sts/db # StatefulSet pod
|
|
1059
|
+
kdebug --controller deploy/frontend --cmd sh # Deployment pod
|
|
1267
1060
|
kdebug --pod web-0 --backup /app/config # Backup files""",
|
|
1268
1061
|
)
|
|
1269
1062
|
|
|
@@ -1279,14 +1072,9 @@ Usage:
|
|
|
1279
1072
|
)
|
|
1280
1073
|
target_group.add_argument(
|
|
1281
1074
|
"--controller",
|
|
1282
|
-
|
|
1283
|
-
metavar="TYPE",
|
|
1284
|
-
help="Controller
|
|
1285
|
-
)
|
|
1286
|
-
target_group.add_argument(
|
|
1287
|
-
"--controller-name",
|
|
1288
|
-
metavar="NAME",
|
|
1289
|
-
help="Controller name (required with --controller)",
|
|
1075
|
+
type=parse_controller_arg,
|
|
1076
|
+
metavar="TYPE/NAME",
|
|
1077
|
+
help="Controller as TYPE/NAME (e.g. sts/myapp, deploy/frontend)",
|
|
1290
1078
|
)
|
|
1291
1079
|
|
|
1292
1080
|
# Options arguments
|
|
@@ -1349,7 +1137,7 @@ Usage:
|
|
|
1349
1137
|
)
|
|
1350
1138
|
util_group.add_argument(
|
|
1351
1139
|
"--completions",
|
|
1352
|
-
choices=["bash", "zsh"],
|
|
1140
|
+
choices=["bash", "zsh", "fish"],
|
|
1353
1141
|
metavar="SHELL",
|
|
1354
1142
|
help="Output shell completion script",
|
|
1355
1143
|
)
|
|
@@ -1358,10 +1146,7 @@ Usage:
|
|
|
1358
1146
|
|
|
1359
1147
|
# Handle --completions early
|
|
1360
1148
|
if args.completions:
|
|
1361
|
-
|
|
1362
|
-
print(generate_bash_completion())
|
|
1363
|
-
else:
|
|
1364
|
-
print(generate_zsh_completion())
|
|
1149
|
+
_output_completion_script(args.completions)
|
|
1365
1150
|
sys.exit(0)
|
|
1366
1151
|
|
|
1367
1152
|
# Set debug mode and kubectl global options
|
|
@@ -1370,10 +1155,6 @@ Usage:
|
|
|
1370
1155
|
KUBECTL_CONTEXT = args.context
|
|
1371
1156
|
KUBECTL_KUBECONFIG = args.kubeconfig
|
|
1372
1157
|
|
|
1373
|
-
# Validate arguments - allow interactive mode if no pod/controller specified
|
|
1374
|
-
if args.controller and not args.controller_name:
|
|
1375
|
-
parser.error("--controller-name is required when using --controller")
|
|
1376
|
-
|
|
1377
1158
|
# Select pod
|
|
1378
1159
|
pod = select_pod(args)
|
|
1379
1160
|
if not pod:
|
|
File without changes
|
|
@@ -31,20 +31,41 @@ _kdebug_pods() {
|
|
|
31
31
|
_describe 'pod' pods
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
_kdebug_controllers() {
|
|
35
35
|
local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
|
|
36
|
-
local ct="${opt_args[--controller]:-deployment}"
|
|
37
36
|
local kubectl_args=$(_kdebug_kubectl_args)
|
|
38
|
-
local
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
local cur_word="${words[CURRENT]}"
|
|
38
|
+
|
|
39
|
+
if [[ "$cur_word" == */* ]]; then
|
|
40
|
+
# User typed TYPE/ - complete the name
|
|
41
|
+
local ct="${cur_word%%/*}"
|
|
42
|
+
local resource
|
|
43
|
+
case "$ct" in
|
|
44
|
+
deployment|deploy) resource="deployments" ;;
|
|
45
|
+
statefulset|sts) resource="statefulsets" ;;
|
|
46
|
+
daemonset|ds) resource="daemonsets" ;;
|
|
47
|
+
*) resource="deployments" ;;
|
|
48
|
+
esac
|
|
49
|
+
local -a names
|
|
50
|
+
names=(${(f)"$(kubectl $kubectl_args get "$resource" -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)"})
|
|
51
|
+
local -a completions
|
|
52
|
+
for name in "${names[@]}"; do
|
|
53
|
+
completions+=("${ct}/${name}")
|
|
54
|
+
done
|
|
55
|
+
compadd -Q -- "${completions[@]}"
|
|
56
|
+
else
|
|
57
|
+
# Complete the type prefix
|
|
58
|
+
local -a prefixes
|
|
59
|
+
prefixes=(
|
|
60
|
+
'deployment/:Deployment'
|
|
61
|
+
'deploy/:Deployment (short)'
|
|
62
|
+
'statefulset/:StatefulSet'
|
|
63
|
+
'sts/:StatefulSet (short)'
|
|
64
|
+
'daemonset/:DaemonSet'
|
|
65
|
+
'ds/:DaemonSet (short)'
|
|
66
|
+
)
|
|
67
|
+
_describe 'controller type' prefixes -S ''
|
|
68
|
+
fi
|
|
48
69
|
}
|
|
49
70
|
|
|
50
71
|
_kdebug() {
|
|
@@ -53,8 +74,7 @@ _kdebug() {
|
|
|
53
74
|
'(-V --version)'{-V,--version}'[Show version and exit]'
|
|
54
75
|
'(-h --help)'{-h,--help}'[Show help message]'
|
|
55
76
|
'--pod[Pod name for direct selection]:pod:_kdebug_pods'
|
|
56
|
-
'--controller[Controller
|
|
57
|
-
'--controller-name[Controller name]:name:_kdebug_controller_names'
|
|
77
|
+
'--controller[Controller as TYPE/NAME]:controller:_kdebug_controllers'
|
|
58
78
|
'(-n --namespace)'{-n,--namespace}'[Kubernetes namespace]:namespace:_kdebug_namespaces'
|
|
59
79
|
'--context[Kubernetes context to use]:context:_kdebug_contexts'
|
|
60
80
|
'--kubeconfig[Path to kubeconfig file]:path:_files'
|
|
@@ -66,10 +86,9 @@ _kdebug() {
|
|
|
66
86
|
'--compress[Compress backup as tar.gz]'
|
|
67
87
|
'--as-root[Run debug container as root]'
|
|
68
88
|
'--debug[Show kubectl commands being executed]'
|
|
69
|
-
'--completions[Output shell completion script]:shell:(bash zsh)'
|
|
89
|
+
'--completions[Output shell completion script]:shell:(bash zsh fish)'
|
|
70
90
|
)
|
|
71
91
|
_arguments -s $args
|
|
72
92
|
}
|
|
73
93
|
|
|
74
94
|
_kdebug "$@"
|
|
75
|
-
|
|
@@ -81,33 +81,15 @@ _kdebug_get_namespace_from_args() {
|
|
|
81
81
|
kubectl $kubectl_args config view --minify -o jsonpath='{..namespace}' 2>/dev/null || echo "default"
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
_kdebug_get_controller_from_args() {
|
|
85
|
-
local i
|
|
86
|
-
for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
|
|
87
|
-
case "${COMP_WORDS[i]}" in
|
|
88
|
-
--controller)
|
|
89
|
-
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
90
|
-
echo "${COMP_WORDS[$((i+1))]}"
|
|
91
|
-
return
|
|
92
|
-
fi
|
|
93
|
-
;;
|
|
94
|
-
--controller=*)
|
|
95
|
-
echo "${COMP_WORDS[i]#*=}"
|
|
96
|
-
return
|
|
97
|
-
;;
|
|
98
|
-
esac
|
|
99
|
-
done
|
|
100
|
-
}
|
|
101
|
-
|
|
102
84
|
_kdebug() {
|
|
103
85
|
local cur prev words cword
|
|
104
86
|
_init_completion || return
|
|
105
87
|
|
|
106
|
-
local opts="--pod --controller
|
|
88
|
+
local opts="--pod --controller -n --namespace --context --kubeconfig
|
|
107
89
|
--container --debug-image --cmd --cd-into --backup --compress --as-root
|
|
108
90
|
--debug --completions -V --version --help -h"
|
|
109
91
|
|
|
110
|
-
local
|
|
92
|
+
local controller_prefixes="deployment/ deploy/ statefulset/ sts/ daemonset/ ds/"
|
|
111
93
|
|
|
112
94
|
case "$prev" in
|
|
113
95
|
-n|--namespace)
|
|
@@ -128,14 +110,20 @@ _kdebug() {
|
|
|
128
110
|
return
|
|
129
111
|
;;
|
|
130
112
|
--controller)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
113
|
+
# Complete TYPE/NAME - if cur contains /, complete the name part
|
|
114
|
+
if [[ "$cur" == */* ]]; then
|
|
115
|
+
local ct="${cur%%/*}"
|
|
116
|
+
local ns=$(_kdebug_get_namespace_from_args)
|
|
117
|
+
local names=$(_kdebug_get_controllers "$ns" "$ct")
|
|
118
|
+
local completions=""
|
|
119
|
+
for name in $names; do
|
|
120
|
+
completions="$completions ${ct}/${name}"
|
|
121
|
+
done
|
|
122
|
+
COMPREPLY=($(compgen -W "$completions" -- "$cur"))
|
|
123
|
+
else
|
|
124
|
+
COMPREPLY=($(compgen -W "$controller_prefixes" -- "$cur"))
|
|
125
|
+
# Don't add trailing space after type prefix
|
|
126
|
+
compopt -o nospace
|
|
139
127
|
fi
|
|
140
128
|
return
|
|
141
129
|
;;
|
|
@@ -144,7 +132,7 @@ _kdebug() {
|
|
|
144
132
|
return
|
|
145
133
|
;;
|
|
146
134
|
--completions)
|
|
147
|
-
COMPREPLY=($(compgen -W "bash zsh" -- "$cur"))
|
|
135
|
+
COMPREPLY=($(compgen -W "bash zsh fish" -- "$cur"))
|
|
148
136
|
return
|
|
149
137
|
;;
|
|
150
138
|
esac
|
|
@@ -156,4 +144,3 @@ _kdebug() {
|
|
|
156
144
|
}
|
|
157
145
|
|
|
158
146
|
complete -F _kdebug kdebug
|
|
159
|
-
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# kdebug fish completion
|
|
2
|
+
# Install: kdebug --completions fish | source
|
|
3
|
+
# Or: kdebug --completions fish > ~/.config/fish/completions/kdebug.fish
|
|
4
|
+
|
|
5
|
+
function __kdebug_get_kubectl_args
|
|
6
|
+
set -l tokens (commandline -opc)
|
|
7
|
+
set -l args
|
|
8
|
+
set -l i 2
|
|
9
|
+
while test $i -le (count $tokens)
|
|
10
|
+
switch $tokens[$i]
|
|
11
|
+
case --context
|
|
12
|
+
set -l next (math $i + 1)
|
|
13
|
+
if test $next -le (count $tokens)
|
|
14
|
+
set -a args --context=$tokens[$next]
|
|
15
|
+
end
|
|
16
|
+
case '--context=*'
|
|
17
|
+
set -a args $tokens[$i]
|
|
18
|
+
case --kubeconfig
|
|
19
|
+
set -l next (math $i + 1)
|
|
20
|
+
if test $next -le (count $tokens)
|
|
21
|
+
set -a args --kubeconfig=$tokens[$next]
|
|
22
|
+
end
|
|
23
|
+
case '--kubeconfig=*'
|
|
24
|
+
set -a args $tokens[$i]
|
|
25
|
+
end
|
|
26
|
+
set i (math $i + 1)
|
|
27
|
+
end
|
|
28
|
+
echo $args
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
function __kdebug_get_namespace_from_args
|
|
32
|
+
set -l tokens (commandline -opc)
|
|
33
|
+
set -l i 2
|
|
34
|
+
while test $i -le (count $tokens)
|
|
35
|
+
switch $tokens[$i]
|
|
36
|
+
case -n --namespace
|
|
37
|
+
set -l next (math $i + 1)
|
|
38
|
+
if test $next -le (count $tokens)
|
|
39
|
+
echo $tokens[$next]
|
|
40
|
+
return
|
|
41
|
+
end
|
|
42
|
+
case '-n=*' '--namespace=*'
|
|
43
|
+
string replace -r '^[^=]+=' '' $tokens[$i]
|
|
44
|
+
return
|
|
45
|
+
end
|
|
46
|
+
set i (math $i + 1)
|
|
47
|
+
end
|
|
48
|
+
set -l kubectl_args (__kdebug_get_kubectl_args)
|
|
49
|
+
set -l ns (kubectl $kubectl_args config view --minify -o jsonpath='{..namespace}' 2>/dev/null)
|
|
50
|
+
if test -n "$ns"
|
|
51
|
+
echo $ns
|
|
52
|
+
else
|
|
53
|
+
echo default
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
function __kdebug_get_contexts
|
|
58
|
+
kubectl config get-contexts -o name 2>/dev/null
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
function __kdebug_get_namespaces
|
|
62
|
+
set -l kubectl_args (__kdebug_get_kubectl_args)
|
|
63
|
+
kubectl $kubectl_args get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
function __kdebug_get_pods
|
|
67
|
+
set -l ns (__kdebug_get_namespace_from_args)
|
|
68
|
+
set -l kubectl_args (__kdebug_get_kubectl_args)
|
|
69
|
+
kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
function __kdebug_get_controllers
|
|
73
|
+
set -l ns (__kdebug_get_namespace_from_args)
|
|
74
|
+
set -l kubectl_args (__kdebug_get_kubectl_args)
|
|
75
|
+
set -l cur (commandline -ct)
|
|
76
|
+
|
|
77
|
+
if string match -q '*/*' -- "$cur"
|
|
78
|
+
# User typed TYPE/ - complete the name part
|
|
79
|
+
set -l ct (string replace -r '/.*' '' -- "$cur")
|
|
80
|
+
set -l resource
|
|
81
|
+
switch $ct
|
|
82
|
+
case deployment deploy
|
|
83
|
+
set resource deployments
|
|
84
|
+
case statefulset sts
|
|
85
|
+
set resource statefulsets
|
|
86
|
+
case daemonset ds
|
|
87
|
+
set resource daemonsets
|
|
88
|
+
case '*'
|
|
89
|
+
return
|
|
90
|
+
end
|
|
91
|
+
for name in (kubectl $kubectl_args get "$resource" -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)
|
|
92
|
+
echo "$ct/$name"
|
|
93
|
+
end
|
|
94
|
+
else
|
|
95
|
+
# Complete type prefixes
|
|
96
|
+
printf '%s\n' deployment/ deploy/ statefulset/ sts/ daemonset/ ds/
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Disable file completions for kdebug
|
|
101
|
+
complete -c kdebug -f
|
|
102
|
+
|
|
103
|
+
# Target selection
|
|
104
|
+
complete -c kdebug -l pod -d 'Pod name for direct selection' -xa '(__kdebug_get_pods)'
|
|
105
|
+
complete -c kdebug -l controller -d 'Controller as TYPE/NAME' -xa '(__kdebug_get_controllers)'
|
|
106
|
+
|
|
107
|
+
# Options
|
|
108
|
+
complete -c kdebug -s n -l namespace -d 'Kubernetes namespace' -xa '(__kdebug_get_namespaces)'
|
|
109
|
+
complete -c kdebug -l context -d 'Kubernetes context to use' -xa '(__kdebug_get_contexts)'
|
|
110
|
+
complete -c kdebug -l kubeconfig -d 'Path to kubeconfig file' -rF
|
|
111
|
+
complete -c kdebug -l container -d 'Target container for process namespace sharing' -x
|
|
112
|
+
complete -c kdebug -l debug-image -d 'Debug container image' -x
|
|
113
|
+
complete -c kdebug -l cmd -d 'Command to run in debug container' -x
|
|
114
|
+
complete -c kdebug -l cd-into -d 'Change to directory on start' -rF
|
|
115
|
+
complete -c kdebug -l backup -d 'Copy path from pod to local backups' -x
|
|
116
|
+
complete -c kdebug -l compress -d 'Compress backup as tar.gz'
|
|
117
|
+
complete -c kdebug -l as-root -d 'Run debug container as root'
|
|
118
|
+
complete -c kdebug -l debug -d 'Show kubectl commands being executed'
|
|
119
|
+
complete -c kdebug -l completions -d 'Output shell completion script' -xa 'bash zsh fish'
|
|
120
|
+
complete -c kdebug -s V -l version -d 'Show version and exit'
|
|
121
|
+
complete -c kdebug -s h -l help -d 'Show help message'
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Uses PyPI Trusted Publisher (OIDC) - no token required
|
|
2
|
-
# Configure at: https://pypi.org/manage/project/kdebug/settings/publishing/
|
|
3
|
-
|
|
4
|
-
name: Publish to PyPI
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
workflow_call:
|
|
8
|
-
inputs:
|
|
9
|
-
ref:
|
|
10
|
-
description: 'Git reference to checkout'
|
|
11
|
-
required: false
|
|
12
|
-
type: string
|
|
13
|
-
release:
|
|
14
|
-
types: [published]
|
|
15
|
-
workflow_dispatch:
|
|
16
|
-
|
|
17
|
-
permissions:
|
|
18
|
-
id-token: write
|
|
19
|
-
contents: read
|
|
20
|
-
|
|
21
|
-
jobs:
|
|
22
|
-
publish:
|
|
23
|
-
runs-on: ubuntu-latest
|
|
24
|
-
environment: pypi
|
|
25
|
-
steps:
|
|
26
|
-
- name: Check out
|
|
27
|
-
uses: actions/checkout@v6
|
|
28
|
-
with:
|
|
29
|
-
ref: ${{ inputs.ref || github.ref }}
|
|
30
|
-
|
|
31
|
-
- name: Install uv
|
|
32
|
-
uses: astral-sh/setup-uv@v7
|
|
33
|
-
with:
|
|
34
|
-
version: "latest"
|
|
35
|
-
|
|
36
|
-
- name: Build package
|
|
37
|
-
run: uv build
|
|
38
|
-
|
|
39
|
-
- name: Publish package
|
|
40
|
-
run: uv publish --trusted-publishing always
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
name: Create Release
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
inputs:
|
|
6
|
-
release_type:
|
|
7
|
-
description: 'Release type'
|
|
8
|
-
required: true
|
|
9
|
-
default: 'patch'
|
|
10
|
-
type: choice
|
|
11
|
-
options:
|
|
12
|
-
- patch
|
|
13
|
-
- minor
|
|
14
|
-
- major
|
|
15
|
-
|
|
16
|
-
permissions:
|
|
17
|
-
contents: write
|
|
18
|
-
id-token: write
|
|
19
|
-
|
|
20
|
-
jobs:
|
|
21
|
-
release:
|
|
22
|
-
runs-on: ubuntu-latest
|
|
23
|
-
outputs:
|
|
24
|
-
version: ${{ steps.new.outputs.version }}
|
|
25
|
-
steps:
|
|
26
|
-
- uses: actions/checkout@v6
|
|
27
|
-
with:
|
|
28
|
-
fetch-depth: 0
|
|
29
|
-
|
|
30
|
-
- name: Configure Git
|
|
31
|
-
run: |
|
|
32
|
-
git config user.name "github-actions[bot]"
|
|
33
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
34
|
-
|
|
35
|
-
- name: Get current version
|
|
36
|
-
id: current
|
|
37
|
-
run: |
|
|
38
|
-
VERSION=$(grep -oP '^version = "\K[^"]+' pyproject.toml)
|
|
39
|
-
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
40
|
-
|
|
41
|
-
- name: Calculate new version
|
|
42
|
-
id: new
|
|
43
|
-
run: |
|
|
44
|
-
IFS='.' read -r major minor patch <<< "${{ steps.current.outputs.version }}"
|
|
45
|
-
case "${{ inputs.release_type }}" in
|
|
46
|
-
major) major=$((major + 1)); minor=0; patch=0 ;;
|
|
47
|
-
minor) minor=$((minor + 1)); patch=0 ;;
|
|
48
|
-
patch) patch=$((patch + 1)) ;;
|
|
49
|
-
esac
|
|
50
|
-
echo "version=${major}.${minor}.${patch}" >> $GITHUB_OUTPUT
|
|
51
|
-
|
|
52
|
-
- name: Update version in pyproject.toml
|
|
53
|
-
run: |
|
|
54
|
-
sed -i 's/^version = "[^"]*"/version = "${{ steps.new.outputs.version }}"/' pyproject.toml
|
|
55
|
-
|
|
56
|
-
- name: Commit and tag
|
|
57
|
-
run: |
|
|
58
|
-
git add pyproject.toml
|
|
59
|
-
git commit -m "Release v${{ steps.new.outputs.version }}"
|
|
60
|
-
git tag "v${{ steps.new.outputs.version }}"
|
|
61
|
-
|
|
62
|
-
- name: Push changes
|
|
63
|
-
run: |
|
|
64
|
-
git push origin HEAD:${{ github.ref_name }}
|
|
65
|
-
git push --tags
|
|
66
|
-
|
|
67
|
-
- name: Create GitHub Release
|
|
68
|
-
env:
|
|
69
|
-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
70
|
-
run: |
|
|
71
|
-
gh release create "v${{ steps.new.outputs.version }}" \
|
|
72
|
-
--generate-notes \
|
|
73
|
-
--latest
|
|
74
|
-
|
|
75
|
-
update-homebrew:
|
|
76
|
-
needs: release
|
|
77
|
-
uses: ./.github/workflows/update-homebrew.yml
|
|
78
|
-
with:
|
|
79
|
-
version: v${{ needs.release.outputs.version }}
|
|
80
|
-
secrets: inherit
|
|
81
|
-
|
|
82
|
-
publish-pypi:
|
|
83
|
-
needs: release
|
|
84
|
-
uses: ./.github/workflows/pypi-publish.yml
|
|
85
|
-
with:
|
|
86
|
-
ref: v${{ needs.release.outputs.version }}
|
|
87
|
-
secrets: inherit
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
name: Update Homebrew Tap
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
workflow_call:
|
|
5
|
-
inputs:
|
|
6
|
-
version:
|
|
7
|
-
description: 'Version tag (e.g., v1.0.0)'
|
|
8
|
-
required: false
|
|
9
|
-
type: string
|
|
10
|
-
|
|
11
|
-
jobs:
|
|
12
|
-
update-homebrew-tap:
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
steps:
|
|
15
|
-
- name: Get version
|
|
16
|
-
id: release-info
|
|
17
|
-
run: |
|
|
18
|
-
VERSION="${{ inputs.version }}"
|
|
19
|
-
VERSION="${VERSION#v}" # Strip 'v' prefix
|
|
20
|
-
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
21
|
-
echo "Release version: $VERSION"
|
|
22
|
-
|
|
23
|
-
- name: Trigger Homebrew tap update
|
|
24
|
-
env:
|
|
25
|
-
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
26
|
-
run: |
|
|
27
|
-
gh workflow run update-formula.yml \
|
|
28
|
-
--repo jessegoodier/homebrew-kdebug \
|
|
29
|
-
-f version="${{ steps.release-info.outputs.version }}" || {
|
|
30
|
-
echo "::warning::Failed to trigger Homebrew update. Ensure HOMEBREW_TAP_TOKEN secret is set with repo scope for jessegoodier/homebrew-kdebug."
|
|
31
|
-
echo "The daily schedule in homebrew-kdebug will pick up the new version from PyPI automatically."
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
- name: Summary
|
|
35
|
-
run: |
|
|
36
|
-
echo "### Homebrew tap update triggered for kdebug ${{ steps.release-info.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
|
37
|
-
echo "The [homebrew-kdebug](https://github.com/jessegoodier/homebrew-kdebug) update-formula workflow has been dispatched." >> $GITHUB_STEP_SUMMARY
|
kdebug-0.2.2/AGENTS.md
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
# AGENTS.md - AI Assistant Guide
|
|
2
|
-
|
|
3
|
-
This file helps AI coding assistants understand the kdebug project.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
kdebug is a Python CLI tool for launching ephemeral debug containers in Kubernetes pods. It provides interactive shell access, backup capabilities, and a TUI for pod selection.
|
|
8
|
-
|
|
9
|
-
## Project Structure
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
kdebug/
|
|
13
|
-
├── pyproject.toml # Package metadata and build config (version source of truth)
|
|
14
|
-
├── src/
|
|
15
|
-
│ └── kdebug/
|
|
16
|
-
│ ├── __init__.py # Package init with __version__ from importlib.metadata
|
|
17
|
-
│ └── cli.py # Main CLI code
|
|
18
|
-
├── completions/
|
|
19
|
-
│ ├── kdebug.bash # Bash completion script (generated)
|
|
20
|
-
│ └── _kdebug # Zsh completion script (generated)
|
|
21
|
-
├── README.md # User documentation
|
|
22
|
-
├── AGENTS.md # This file
|
|
23
|
-
└── .github/
|
|
24
|
-
└── workflows/
|
|
25
|
-
└── release.yml # Release automation (updates pyproject.toml)
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Key Architecture
|
|
29
|
-
|
|
30
|
-
- **Python package**: Installable via `uv tool install kdebug` or `pip install .`
|
|
31
|
-
- **Entry point**: `kdebug` command maps to `kdebug.cli:main`
|
|
32
|
-
- **Version**: Single source of truth in `pyproject.toml`, accessed via `importlib.metadata`
|
|
33
|
-
- **No external dependencies**: Uses Python stdlib only
|
|
34
|
-
- **Completion scripts are generated**: The functions `generate_bash_completion()` and `generate_zsh_completion()` in `src/kdebug/cli.py` produce the completion files
|
|
35
|
-
- **Global state pattern**: Module-level variables (`DEBUG_MODE`, `KUBECTL_CONTEXT`, `KUBECTL_KUBECONFIG`) are set after argument parsing
|
|
36
|
-
|
|
37
|
-
## Making Changes
|
|
38
|
-
|
|
39
|
-
### Adding a new CLI argument
|
|
40
|
-
|
|
41
|
-
1. Add the argument to the appropriate `parser.add_argument_group()` in `main()`
|
|
42
|
-
2. If it affects kubectl commands, update the relevant helper function or `kubectl_base_cmd()`
|
|
43
|
-
3. Update `generate_bash_completion()` - add to `opts` list and add completion case if needed
|
|
44
|
-
4. Update `generate_zsh_completion()` - add to `args` array with appropriate completer
|
|
45
|
-
5. Regenerate completion files (see below)
|
|
46
|
-
6. Update README.md if user-facing
|
|
47
|
-
|
|
48
|
-
### Modifying kubectl commands
|
|
49
|
-
|
|
50
|
-
All kubectl commands should use `kubectl_base_cmd()` to ensure `--context` and `--kubeconfig` are passed through:
|
|
51
|
-
|
|
52
|
-
```python
|
|
53
|
-
cmd = f"{kubectl_base_cmd()} get pods -n {namespace} -o json"
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### Regenerating completion files
|
|
57
|
-
|
|
58
|
-
After modifying the completion generators:
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
# Install package in development mode first
|
|
62
|
-
uv pip install -e .
|
|
63
|
-
|
|
64
|
-
# Then regenerate completions
|
|
65
|
-
kdebug --completions bash > completions/kdebug.bash
|
|
66
|
-
kdebug --completions zsh > completions/_kdebug
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Testing
|
|
70
|
-
|
|
71
|
-
### Manual testing
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
# Install in development mode
|
|
75
|
-
uv pip install -e .
|
|
76
|
-
|
|
77
|
-
# Verify help output
|
|
78
|
-
kdebug --help
|
|
79
|
-
|
|
80
|
-
# Verify version
|
|
81
|
-
kdebug --version
|
|
82
|
-
|
|
83
|
-
# Test with debug mode to see kubectl commands
|
|
84
|
-
kdebug --debug -n <namespace>
|
|
85
|
-
|
|
86
|
-
# Test argument combinations
|
|
87
|
-
kdebug --context <ctx> --kubeconfig <path> -n <ns> --pod <pod>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### Syntax checks
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
# Python syntax
|
|
94
|
-
python3 -m py_compile src/kdebug/cli.py
|
|
95
|
-
|
|
96
|
-
# Bash completion syntax
|
|
97
|
-
bash -n completions/kdebug.bash
|
|
98
|
-
|
|
99
|
-
# Zsh completion syntax
|
|
100
|
-
zsh -n completions/_kdebug
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Testing completions
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
# Bash
|
|
107
|
-
source <(kdebug --completions bash)
|
|
108
|
-
kdebug --<TAB>
|
|
109
|
-
|
|
110
|
-
# Zsh
|
|
111
|
-
source <(kdebug --completions zsh)
|
|
112
|
-
kdebug --<TAB>
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## GitHub Actions & Dependencies
|
|
116
|
-
|
|
117
|
-
**IMPORTANT: Always use the latest stable versions of GitHub Actions and dependencies to avoid security vulnerabilities (CVEs).**
|
|
118
|
-
|
|
119
|
-
### Current Action Versions (keep updated)
|
|
120
|
-
|
|
121
|
-
- `actions/checkout@v6`
|
|
122
|
-
- `astral-sh/setup-uv@v7`
|
|
123
|
-
|
|
124
|
-
### Guidelines
|
|
125
|
-
|
|
126
|
-
1. **Never hardcode old versions** - Check the action's repository for the latest major version
|
|
127
|
-
2. **Use major version tags** (e.g., `@v6`) not specific commits or minor versions
|
|
128
|
-
3. **Dependabot is configured** - Review and merge dependabot PRs promptly
|
|
129
|
-
4. **When adding new actions** - Always check for the latest version first via the action's GitHub repo or marketplace page
|
|
130
|
-
|
|
131
|
-
### Workflow Files
|
|
132
|
-
|
|
133
|
-
- `.github/workflows/release.yml` - Main release automation
|
|
134
|
-
- `.github/workflows/pypi-publish.yml` - PyPI publishing with OIDC trusted publisher
|
|
135
|
-
- `.github/workflows/update-homebrew.yml` - Homebrew tap updates
|
|
136
|
-
|
|
137
|
-
## Code Conventions
|
|
138
|
-
|
|
139
|
-
- Use `colorize()` for colored output
|
|
140
|
-
- Use `run_command()` for executing shell commands
|
|
141
|
-
- Use `print_debug_command()` to show commands when `--debug` is enabled
|
|
142
|
-
- Error messages go to stderr with `file=sys.stderr`
|
|
143
|
-
- Success indicators use green checkmarks: `{colorize('✓', Colors.GREEN)}`
|
|
144
|
-
- Error indicators use red X: `{colorize('✗', Colors.RED)}`
|
|
145
|
-
|
|
146
|
-
## Dependencies
|
|
147
|
-
|
|
148
|
-
- Python 3.8+ (for `importlib.metadata`)
|
|
149
|
-
- kubectl (must be in PATH and configured)
|
|
150
|
-
- No pip packages required
|
|
151
|
-
|
|
152
|
-
## Installation
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
# Via uv (recommended)
|
|
156
|
-
uv tool install kdebug
|
|
157
|
-
|
|
158
|
-
# Via pip
|
|
159
|
-
pip install .
|
|
160
|
-
|
|
161
|
-
# Development mode
|
|
162
|
-
uv pip install -e .
|
|
163
|
-
```
|
kdebug-0.2.2/uv.lock
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|