Skip to content

Commit d6f77c2

Browse files
committed
Add command: d8 k debug
Signed-off-by: Denis Tarabrin <[email protected]>
1 parent 497d6b2 commit d6f77c2

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed

cmd/kubectl.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,124 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
"time"
24+
2025
"github.com/spf13/cobra"
26+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27+
"k8s.io/client-go/kubernetes"
28+
"k8s.io/client-go/rest"
29+
"k8s.io/client-go/tools/clientcmd"
2130
cliflag "k8s.io/component-base/cli/flag"
2231
"k8s.io/component-base/logs"
2332
kubecmd "k8s.io/kubectl/pkg/cmd"
2433
)
2534

35+
const (
36+
cmNamespace = "d8-system"
37+
cmName = "debug-container"
38+
cmImageKey = "image"
39+
)
40+
41+
func getKubeConfig(kubeconfigPath string) (*rest.Config, error) {
42+
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
43+
44+
if kubeconfigPath != "" {
45+
loadingRules.ExplicitPath = kubeconfigPath
46+
}
47+
48+
configOverrides := &clientcmd.ConfigOverrides{}
49+
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, configOverrides)
50+
51+
config, err := kubeConfig.ClientConfig()
52+
if err != nil {
53+
return nil, fmt.Errorf("failed to load kubernetes config: %w", err)
54+
}
55+
56+
return config, nil
57+
}
58+
59+
func getDebugImage(cmd *cobra.Command) (string, error) {
60+
kubeconfigPath, err := cmd.Flags().GetString("kubeconfig")
61+
if err != nil {
62+
return "", fmt.Errorf("failed to get kubeconfig flag: %w", err)
63+
}
64+
65+
config, err := getKubeConfig(kubeconfigPath)
66+
if err != nil {
67+
return "", fmt.Errorf("failed to setup Kubernetes client: %w", err)
68+
}
69+
70+
kubeCl, err := kubernetes.NewForConfig(config)
71+
if err != nil {
72+
return "", fmt.Errorf("failed to create Kubernetes client: %w", err)
73+
}
74+
75+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
76+
defer cancel()
77+
configMap, err := kubeCl.CoreV1().ConfigMaps(cmNamespace).Get(ctx, cmName, v1.GetOptions{})
78+
if err != nil {
79+
return "", fmt.Errorf("failed to get ConfigMap %s/%s: %w", cmNamespace, cmName, err)
80+
}
81+
82+
imageName, ok := configMap.Data[cmImageKey]
83+
if !ok {
84+
return "", fmt.Errorf("key '%s' not found in ConfigMap %s/%s", cmImageKey, cmNamespace, cmName)
85+
}
86+
87+
if imageName == "" {
88+
return "", fmt.Errorf("image name is empty in ConfigMap %s/%s", cmNamespace, cmName)
89+
}
90+
91+
return imageName, nil
92+
}
93+
2694
func init() {
2795
kubectlCmd := kubecmd.NewDefaultKubectlCommand()
2896
kubectlCmd.Use = "k"
2997
kubectlCmd.Aliases = []string{"kubectl"}
3098
kubectlCmd = ReplaceCommandName("kubectl", "d8 k", kubectlCmd)
3199

100+
var debugCmd *cobra.Command
101+
for _, cmd := range kubectlCmd.Commands() {
102+
if cmd.Name() == "debug" {
103+
debugCmd = cmd
104+
break
105+
}
106+
}
107+
108+
if debugCmd != nil {
109+
if imageFlag := debugCmd.Flags().Lookup("image"); imageFlag != nil {
110+
imageFlag.Usage = "Container image to use for debug container. If not specified, the platform's recommended image will be used."
111+
}
112+
}
113+
114+
rootCmd.PersistentFlags().String("kubeconfig", "", "Path to the kubeconfig file")
115+
116+
originalPersistentPreRunE := kubectlCmd.PersistentPreRunE
117+
kubectlCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
118+
if cmd.Name() == "debug" || (cmd.Parent() != nil && cmd.Parent().Name() == "debug") {
119+
imageFlag := cmd.Flags().Lookup("image")
120+
if imageFlag != nil && imageFlag.Value.String() == "" {
121+
debugImage, err := getDebugImage(cmd)
122+
if err != nil {
123+
fmt.Fprintf(os.Stderr, "Warning: cannot get debug container image from cluster: %v\n", err)
124+
fmt.Fprintf(os.Stderr, "Continuing with default kubectl behavior...\n")
125+
} else {
126+
fmt.Fprintf(os.Stderr, "Using debug container image: %s\n", debugImage)
127+
cmd.Flags().Set("image", debugImage)
128+
}
129+
}
130+
}
131+
132+
if originalPersistentPreRunE != nil {
133+
return originalPersistentPreRunE(cmd, args)
134+
}
135+
return nil
136+
}
137+
32138
// Based on https://github.com/kubernetes/kubernetes/blob/v1.29.3/staging/src/k8s.io/component-base/cli/run.go#L88
33139

34140
kubectlCmd.SetGlobalNormalizationFunc(cliflag.WordSepNormalizeFunc)

0 commit comments

Comments
 (0)