kdebug 0.2.3__py3-none-any.whl → 0.3.1__py3-none-any.whl
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/cli.py +47 -266
- kdebug/completions/__init__.py +0 -0
- kdebug/completions/_kdebug +94 -0
- kdebug/completions/kdebug.bash +146 -0
- kdebug/completions/kdebug.fish +121 -0
- {kdebug-0.2.3.dist-info → kdebug-0.3.1.dist-info}/METADATA +2 -2
- kdebug-0.3.1.dist-info/RECORD +10 -0
- kdebug-0.2.3.dist-info/RECORD +0 -6
- {kdebug-0.2.3.dist-info → kdebug-0.3.1.dist-info}/WHEEL +0 -0
- {kdebug-0.2.3.dist-info → kdebug-0.3.1.dist-info}/entry_points.txt +0 -0
kdebug/cli.py
CHANGED
|
@@ -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
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#compdef kdebug
|
|
2
|
+
# kdebug zsh completion
|
|
3
|
+
# Install: kdebug --completions zsh > ~/.zsh/completions/_kdebug
|
|
4
|
+
# Or: source <(kdebug --completions zsh)
|
|
5
|
+
|
|
6
|
+
_kdebug_kubectl_args() {
|
|
7
|
+
local args=""
|
|
8
|
+
[[ -n "${opt_args[--context]}" ]] && args="$args --context=${opt_args[--context]}"
|
|
9
|
+
[[ -n "${opt_args[--kubeconfig]}" ]] && args="$args --kubeconfig=${opt_args[--kubeconfig]}"
|
|
10
|
+
echo "$args"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
_kdebug_contexts() {
|
|
14
|
+
local -a contexts
|
|
15
|
+
contexts=(${(f)"$(kubectl config get-contexts -o name 2>/dev/null)"})
|
|
16
|
+
_describe 'context' contexts
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
_kdebug_namespaces() {
|
|
20
|
+
local kubectl_args=$(_kdebug_kubectl_args)
|
|
21
|
+
local -a namespaces
|
|
22
|
+
namespaces=(${(f)"$(kubectl $kubectl_args get namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)"})
|
|
23
|
+
_describe 'namespace' namespaces
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
_kdebug_pods() {
|
|
27
|
+
local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
|
|
28
|
+
local kubectl_args=$(_kdebug_kubectl_args)
|
|
29
|
+
local -a pods
|
|
30
|
+
pods=(${(f)"$(kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' 2>/dev/null)"})
|
|
31
|
+
_describe 'pod' pods
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_kdebug_controllers() {
|
|
35
|
+
local ns="${opt_args[-n]:-${opt_args[--namespace]:-default}}"
|
|
36
|
+
local kubectl_args=$(_kdebug_kubectl_args)
|
|
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
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_kdebug() {
|
|
72
|
+
local -a args
|
|
73
|
+
args=(
|
|
74
|
+
'(-V --version)'{-V,--version}'[Show version and exit]'
|
|
75
|
+
'(-h --help)'{-h,--help}'[Show help message]'
|
|
76
|
+
'--pod[Pod name for direct selection]:pod:_kdebug_pods'
|
|
77
|
+
'--controller[Controller as TYPE/NAME]:controller:_kdebug_controllers'
|
|
78
|
+
'(-n --namespace)'{-n,--namespace}'[Kubernetes namespace]:namespace:_kdebug_namespaces'
|
|
79
|
+
'--context[Kubernetes context to use]:context:_kdebug_contexts'
|
|
80
|
+
'--kubeconfig[Path to kubeconfig file]:path:_files'
|
|
81
|
+
'--container[Target container for process namespace sharing]:container:'
|
|
82
|
+
'--debug-image[Debug container image]:image:'
|
|
83
|
+
'--cmd[Command to run in debug container]:command:'
|
|
84
|
+
'--cd-into[Change to directory on start]:directory:_files -/'
|
|
85
|
+
'--backup[Copy path from pod to local backups]:path:'
|
|
86
|
+
'--compress[Compress backup as tar.gz]'
|
|
87
|
+
'--as-root[Run debug container as root]'
|
|
88
|
+
'--debug[Show kubectl commands being executed]'
|
|
89
|
+
'--completions[Output shell completion script]:shell:(bash zsh fish)'
|
|
90
|
+
)
|
|
91
|
+
_arguments -s $args
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_kdebug "$@"
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# kdebug bash completion
|
|
2
|
+
# Source this file or add to ~/.bashrc:
|
|
3
|
+
# source <(kdebug --completions bash)
|
|
4
|
+
# Or:
|
|
5
|
+
# source /path/to/completions/kdebug.bash
|
|
6
|
+
|
|
7
|
+
_kdebug_get_contexts() {
|
|
8
|
+
kubectl config get-contexts -o name 2>/dev/null
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
_kdebug_get_namespaces() {
|
|
12
|
+
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
13
|
+
kubectl $kubectl_args get namespaces -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_kdebug_get_pods() {
|
|
17
|
+
local ns="${1:-default}"
|
|
18
|
+
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
19
|
+
kubectl $kubectl_args get pods -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
_kdebug_get_controllers() {
|
|
23
|
+
local ns="${1:-default}"
|
|
24
|
+
local controller_type="$2"
|
|
25
|
+
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
26
|
+
case "$controller_type" in
|
|
27
|
+
deployment|deploy)
|
|
28
|
+
kubectl $kubectl_args get deployments -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
29
|
+
;;
|
|
30
|
+
statefulset|sts)
|
|
31
|
+
kubectl $kubectl_args get statefulsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
32
|
+
;;
|
|
33
|
+
daemonset|ds)
|
|
34
|
+
kubectl $kubectl_args get daemonsets -n "$ns" -o jsonpath='{.items[*].metadata.name}' 2>/dev/null
|
|
35
|
+
;;
|
|
36
|
+
esac
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
_kdebug_get_kubectl_args() {
|
|
40
|
+
local i args=""
|
|
41
|
+
for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
|
|
42
|
+
case "${COMP_WORDS[i]}" in
|
|
43
|
+
--context)
|
|
44
|
+
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
45
|
+
args="$args --context=${COMP_WORDS[$((i+1))]}"
|
|
46
|
+
fi
|
|
47
|
+
;;
|
|
48
|
+
--context=*)
|
|
49
|
+
args="$args ${COMP_WORDS[i]}"
|
|
50
|
+
;;
|
|
51
|
+
--kubeconfig)
|
|
52
|
+
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
53
|
+
args="$args --kubeconfig=${COMP_WORDS[$((i+1))]}"
|
|
54
|
+
fi
|
|
55
|
+
;;
|
|
56
|
+
--kubeconfig=*)
|
|
57
|
+
args="$args ${COMP_WORDS[i]}"
|
|
58
|
+
;;
|
|
59
|
+
esac
|
|
60
|
+
done
|
|
61
|
+
echo "$args"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
_kdebug_get_namespace_from_args() {
|
|
65
|
+
local i
|
|
66
|
+
for ((i=1; i < ${#COMP_WORDS[@]}; i++)); do
|
|
67
|
+
case "${COMP_WORDS[i]}" in
|
|
68
|
+
-n|--namespace)
|
|
69
|
+
if [[ $((i+1)) -lt ${#COMP_WORDS[@]} ]]; then
|
|
70
|
+
echo "${COMP_WORDS[$((i+1))]}"
|
|
71
|
+
return
|
|
72
|
+
fi
|
|
73
|
+
;;
|
|
74
|
+
-n=*|--namespace=*)
|
|
75
|
+
echo "${COMP_WORDS[i]#*=}"
|
|
76
|
+
return
|
|
77
|
+
;;
|
|
78
|
+
esac
|
|
79
|
+
done
|
|
80
|
+
local kubectl_args=$(_kdebug_get_kubectl_args)
|
|
81
|
+
kubectl $kubectl_args config view --minify -o jsonpath='{..namespace}' 2>/dev/null || echo "default"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
_kdebug() {
|
|
85
|
+
local cur prev words cword
|
|
86
|
+
_init_completion || return
|
|
87
|
+
|
|
88
|
+
local opts="--pod --controller -n --namespace --context --kubeconfig
|
|
89
|
+
--container --debug-image --cmd --cd-into --backup --compress --as-root
|
|
90
|
+
--debug --completions -V --version --help -h"
|
|
91
|
+
|
|
92
|
+
local controller_prefixes="deployment/ deploy/ statefulset/ sts/ daemonset/ ds/"
|
|
93
|
+
|
|
94
|
+
case "$prev" in
|
|
95
|
+
-n|--namespace)
|
|
96
|
+
COMPREPLY=($(compgen -W "$(_kdebug_get_namespaces)" -- "$cur"))
|
|
97
|
+
return
|
|
98
|
+
;;
|
|
99
|
+
--context)
|
|
100
|
+
COMPREPLY=($(compgen -W "$(_kdebug_get_contexts)" -- "$cur"))
|
|
101
|
+
return
|
|
102
|
+
;;
|
|
103
|
+
--kubeconfig)
|
|
104
|
+
_filedir
|
|
105
|
+
return
|
|
106
|
+
;;
|
|
107
|
+
--pod)
|
|
108
|
+
local ns=$(_kdebug_get_namespace_from_args)
|
|
109
|
+
COMPREPLY=($(compgen -W "$(_kdebug_get_pods "$ns")" -- "$cur"))
|
|
110
|
+
return
|
|
111
|
+
;;
|
|
112
|
+
--controller)
|
|
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
|
|
127
|
+
fi
|
|
128
|
+
return
|
|
129
|
+
;;
|
|
130
|
+
--container|--debug-image|--cmd|--cd-into|--backup)
|
|
131
|
+
# These take arbitrary values, no completion
|
|
132
|
+
return
|
|
133
|
+
;;
|
|
134
|
+
--completions)
|
|
135
|
+
COMPREPLY=($(compgen -W "bash zsh fish" -- "$cur"))
|
|
136
|
+
return
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
139
|
+
|
|
140
|
+
if [[ "$cur" == -* ]]; then
|
|
141
|
+
COMPREPLY=($(compgen -W "$opts" -- "$cur"))
|
|
142
|
+
return
|
|
143
|
+
fi
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
complete -F _kdebug kdebug
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kdebug
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
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
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
kdebug/__init__.py,sha256=OOhp8y3zVAw6RzVcSq4wtyeAzPneUnVw-b2OIXtjgTc,182
|
|
2
|
+
kdebug/cli.py,sha256=c6dWkjD2d-c7lEDjUX9x0MTirHaxIYIrNV_Lg9umMJw,42047
|
|
3
|
+
kdebug/completions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
kdebug/completions/_kdebug,sha256=xa4h4pE-awN3Kb5HA7GMBuu8vTMrKg_6PKy9Q0X3iXE,3539
|
|
5
|
+
kdebug/completions/kdebug.bash,sha256=HkNrBKLIDojWrWPq9QXA9sd6k79LnUBEqW8Es2Rf5FE,4731
|
|
6
|
+
kdebug/completions/kdebug.fish,sha256=kzJ4ww0-IyXduYqEHFTNKLLHSZ9Jad9oOEAoweYjKuU,4469
|
|
7
|
+
kdebug-0.3.1.dist-info/METADATA,sha256=tSCzCfUkE37yoFYP9OCFXnofcsFnbk8HlIZHYodD99I,10044
|
|
8
|
+
kdebug-0.3.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
9
|
+
kdebug-0.3.1.dist-info/entry_points.txt,sha256=SSMhCgTQLJEK7RwCvlEiskLgk3_zXzTssTu6d-1_sJo,43
|
|
10
|
+
kdebug-0.3.1.dist-info/RECORD,,
|
kdebug-0.2.3.dist-info/RECORD
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
kdebug/__init__.py,sha256=OOhp8y3zVAw6RzVcSq4wtyeAzPneUnVw-b2OIXtjgTc,182
|
|
2
|
-
kdebug/cli.py,sha256=OBeBwem1AzinYYn-90XgFOpOemB1R09XxlS48o9r84M,49147
|
|
3
|
-
kdebug-0.2.3.dist-info/METADATA,sha256=7RCK9i9IPq5Sw9eipFHrDB2Z0j9UOKJAjkNQ_BPmU4o,10044
|
|
4
|
-
kdebug-0.2.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
5
|
-
kdebug-0.2.3.dist-info/entry_points.txt,sha256=SSMhCgTQLJEK7RwCvlEiskLgk3_zXzTssTu6d-1_sJo,43
|
|
6
|
-
kdebug-0.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|