Skip to content

Commit 0483850

Browse files
medyagheinyx
authored andcommitted
Update OWNERS: adding nirs to reviewers (#21016)
1 parent d2be13e commit 0483850

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3667
-124
lines changed

OWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ reviewers:
44
- medyagh
55
- prezha
66
- comradeprogrammer
7+
- nirs
78
approvers:
89
- medyagh
910
- spowelljr

cmd/minikube/cmd/ssh.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import (
2929
"k8s.io/minikube/pkg/minikube/node"
3030
"k8s.io/minikube/pkg/minikube/out"
3131
"k8s.io/minikube/pkg/minikube/reason"
32+
"k8s.io/minikube/pkg/drivers/kic/oci"
33+
"k8s.io/klog/v2"
3234
)
3335

3436
var nativeSSHClient bool
@@ -56,7 +58,16 @@ var sshCmd = &cobra.Command{
5658
}
5759
}
5860

59-
err = machine.CreateSSHShell(co.API, *co.Config, *n, args, nativeSSHClient)
61+
// For remote Docker contexts, use docker exec instead of SSH
62+
klog.Warningf("SSH Command: Driver=%s, IsRemoteDockerContext=%v", co.Config.Driver, oci.IsRemoteDockerContext())
63+
if co.Config.Driver == driver.Docker && oci.IsRemoteDockerContext() {
64+
klog.Warningf("Using CreateSSHTerminal for remote Docker context")
65+
err = oci.CreateSSHTerminal(config.MachineName(*co.Config, *n), args)
66+
} else {
67+
klog.Warningf("Using standard SSH shell")
68+
err = machine.CreateSSHShell(co.API, *co.Config, *n, args, nativeSSHClient)
69+
}
70+
6071
if err != nil {
6172
// This is typically due to a non-zero exit code, so no need for flourish.
6273
out.ErrLn("ssh: %v", err)

cmd/minikube/cmd/start.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ import (
4141
"github.com/google/go-containerregistry/pkg/name"
4242
"github.com/google/go-containerregistry/pkg/v1/remote"
4343
"github.com/pkg/errors"
44-
"github.com/shirou/gopsutil/v3/cpu"
45-
gopshost "github.com/shirou/gopsutil/v3/host"
44+
"github.com/shirou/gopsutil/v4/cpu"
45+
gopshost "github.com/shirou/gopsutil/v4/host"
4646
"github.com/spf13/cobra"
4747
"github.com/spf13/viper"
4848
"golang.org/x/text/cases"
@@ -113,10 +113,11 @@ func init() {
113113

114114
// startCmd represents the start command
115115
var startCmd = &cobra.Command{
116-
Use: "start",
117-
Short: "Starts a local Kubernetes cluster",
118-
Long: "Starts a local Kubernetes cluster",
119-
Run: runStart,
116+
Use: "start",
117+
Aliases: []string{"create"},
118+
Short: "Starts a local Kubernetes cluster",
119+
Long: "Starts a local Kubernetes cluster",
120+
Run: runStart,
120121
}
121122

122123
// platform generates a user-readable platform message
@@ -135,7 +136,12 @@ func platform() string {
135136

136137
vsys, vrole, err := gopshost.Virtualization()
137138
if err != nil {
138-
klog.Warningf("gopshost.Virtualization returned error: %v", err)
139+
// Only log if it's a real error, not just "not implemented yet"
140+
if !strings.Contains(err.Error(), "not implemented yet") {
141+
klog.Warningf("gopshost.Virtualization returned error: %v", err)
142+
} else {
143+
klog.V(3).Infof("Virtualization detection not implemented for this platform (harmless)")
144+
}
139145
} else {
140146
klog.Infof("virtualization: %s %s", vsys, vrole)
141147
}
@@ -731,6 +737,14 @@ func selectDriver(existing *config.ClusterConfig) (registry.DriverState, []regis
731737
return ds, nil, true
732738
}
733739

740+
// Check for remote Docker context and auto-select docker driver
741+
if oci.IsRemoteDockerContext() {
742+
ds := driver.Status("docker")
743+
out.Step(style.Sparkle, `Detected a remote Docker context, using the {{.driver}} driver`, out.V{"driver": ds.String()})
744+
out.Infof("For remote Docker connections, you may need to run 'minikube tunnel-ssh' for API server access")
745+
return ds, nil, true
746+
}
747+
734748
choices := driver.Choices(viper.GetBool("vm"))
735749
pick, alts, rejects := driver.Suggest(choices)
736750
if pick.Name == "" {

cmd/minikube/cmd/start_flags.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424

2525
"github.com/blang/semver/v4"
2626
"github.com/pkg/errors"
27-
"github.com/shirou/gopsutil/v3/cpu"
27+
"github.com/shirou/gopsutil/v4/cpu"
2828
"github.com/spf13/cobra"
2929
"github.com/spf13/viper"
3030
"k8s.io/klog/v2"

cmd/minikube/cmd/tunnel-ssh.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cmd
18+
19+
import (
20+
"fmt"
21+
"os"
22+
"os/signal"
23+
"strconv"
24+
"syscall"
25+
26+
"github.com/spf13/cobra"
27+
"k8s.io/klog/v2"
28+
"k8s.io/minikube/pkg/drivers/kic/oci"
29+
"k8s.io/minikube/pkg/minikube/exit"
30+
"k8s.io/minikube/pkg/minikube/kubeconfig"
31+
"k8s.io/minikube/pkg/minikube/mustload"
32+
"k8s.io/minikube/pkg/minikube/out"
33+
"k8s.io/minikube/pkg/minikube/reason"
34+
"k8s.io/minikube/pkg/minikube/style"
35+
)
36+
37+
// tunnelSSHCmd represents the tunnel-ssh command for persistent SSH tunneling
38+
var tunnelSSHCmd = &cobra.Command{
39+
Use: "tunnel-ssh",
40+
Short: "Create persistent SSH tunnel for remote Docker contexts",
41+
Long: `Creates and maintains an SSH tunnel for API server access when using
42+
remote Docker contexts. The tunnel runs in the foreground and can be stopped with Ctrl+C.`,
43+
Run: func(_ *cobra.Command, _ []string) {
44+
// Check if we're using a remote SSH Docker context
45+
if !oci.IsRemoteDockerContext() {
46+
out.Styled(style.Meh, "No remote Docker context detected - tunnel not needed")
47+
return
48+
}
49+
50+
if !oci.IsSSHDockerContext() {
51+
out.ErrT(style.Sad, "SSH tunnel only supported for SSH-based Docker contexts")
52+
exit.Error(reason.Usage, "unsupported context type", fmt.Errorf("not an SSH context"))
53+
}
54+
55+
cname := ClusterFlagValue()
56+
co := mustload.Running(cname)
57+
58+
out.Step(style.Launch, "Starting SSH tunnel for API server access...")
59+
klog.Infof("Setting up persistent SSH tunnel for cluster %s", cname)
60+
61+
// Set up SSH tunnel for API server access
62+
tunnelEndpoint, cleanup, err := oci.SetupAPIServerTunnel(co.CP.Port)
63+
if err != nil {
64+
exit.Error(reason.HostKubeconfigUpdate, "setting up SSH tunnel", err)
65+
}
66+
67+
if tunnelEndpoint == "" {
68+
out.Styled(style.Meh, "No tunnel needed for this context")
69+
return
70+
}
71+
72+
// Parse tunnel endpoint to get port
73+
var tunnelPort int
74+
if len(tunnelEndpoint) > 19 { // len("https://localhost:")
75+
portStr := tunnelEndpoint[19:] // Skip "https://localhost:"
76+
if port, parseErr := strconv.Atoi(portStr); parseErr == nil {
77+
tunnelPort = port
78+
}
79+
}
80+
81+
// Update kubeconfig to use the tunnel
82+
updated, err := kubeconfig.UpdateEndpoint(cname, "localhost", tunnelPort, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
83+
if err != nil {
84+
cleanup()
85+
exit.Error(reason.HostKubeconfigUpdate, "updating kubeconfig", err)
86+
}
87+
88+
if updated {
89+
out.Step(style.Celebrate, `"{{.context}}" context updated to use SSH tunnel {{.endpoint}}`,
90+
out.V{"context": cname, "endpoint": tunnelEndpoint})
91+
}
92+
93+
out.Step(style.Running, "SSH tunnel active on {{.endpoint}} ({{.original}} -> localhost:{{.port}})",
94+
out.V{
95+
"endpoint": tunnelEndpoint,
96+
"original": fmt.Sprintf("%s:%d", co.CP.Hostname, co.CP.Port),
97+
"port": tunnelPort,
98+
})
99+
out.Styled(style.Tip, "Press Ctrl+C to stop the tunnel")
100+
101+
// Set up signal handling for graceful shutdown
102+
c := make(chan os.Signal, 1)
103+
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
104+
105+
// Wait for interrupt signal
106+
<-c
107+
out.Step(style.Shutdown, "Stopping SSH tunnel...")
108+
cleanup()
109+
out.Styled(style.Celebrate, "SSH tunnel stopped")
110+
},
111+
}
112+
113+
func init() {
114+
RootCmd.AddCommand(tunnelSSHCmd)
115+
}

cmd/minikube/cmd/update-context.go

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
"net/url"
21+
"strconv"
22+
2023
"github.com/spf13/cobra"
24+
"k8s.io/klog/v2"
25+
"k8s.io/minikube/pkg/drivers/kic/oci"
2126
"k8s.io/minikube/pkg/minikube/exit"
2227
"k8s.io/minikube/pkg/minikube/kubeconfig"
2328
"k8s.io/minikube/pkg/minikube/mustload"
@@ -35,14 +40,72 @@ var updateContextCmd = &cobra.Command{
3540
Run: func(_ *cobra.Command, _ []string) {
3641
cname := ClusterFlagValue()
3742
co := mustload.Running(cname)
38-
// cluster extension metada for kubeconfig
3943

40-
updated, err := kubeconfig.UpdateEndpoint(cname, co.CP.Hostname, co.CP.Port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
44+
// Determine the endpoint to use (with tunneling or remote host)
45+
hostname := co.CP.Hostname
46+
port := co.CP.Port
47+
48+
// Handle remote Docker contexts
49+
if oci.IsRemoteDockerContext() {
50+
if oci.IsSSHDockerContext() {
51+
klog.Infof("Remote SSH Docker context detected, setting up API server tunnel")
52+
53+
// Set up SSH tunnel for API server access
54+
tunnelEndpoint, cleanup, err := oci.SetupAPIServerTunnel(co.CP.Port)
55+
if err != nil {
56+
klog.Warningf("Failed to setup SSH tunnel, falling back to direct connection: %v", err)
57+
} else if tunnelEndpoint != "" {
58+
// Parse the tunnel endpoint to get localhost and tunnel port
59+
hostname = "localhost"
60+
// Extract port from tunnelEndpoint (format: https://localhost:PORT)
61+
if len(tunnelEndpoint) > 19 { // len("https://localhost:")
62+
portStr := tunnelEndpoint[19:] // Skip "https://localhost:"
63+
if tunneledPort, parseErr := strconv.Atoi(portStr); parseErr == nil {
64+
port = tunneledPort
65+
klog.Infof("Using SSH tunnel: %s -> %s:%d", tunnelEndpoint, co.CP.Hostname, co.CP.Port)
66+
67+
// Set up cleanup when the process exits
68+
defer func() {
69+
klog.Infof("Cleaning up SSH tunnel")
70+
cleanup()
71+
}()
72+
}
73+
}
74+
}
75+
} else {
76+
// TLS context - use the actual remote host (Docker TLS doesn't provide port forwarding)
77+
klog.Infof("Remote TLS Docker context detected, using direct connection to remote host")
78+
79+
ctx, err := oci.GetCurrentContext()
80+
if err == nil && ctx.Host != "" {
81+
if u, parseErr := url.Parse(ctx.Host); parseErr == nil && u.Hostname() != "" {
82+
hostname = u.Hostname()
83+
klog.Infof("Using remote host for TLS context: %s (port %d)", hostname, port)
84+
} else {
85+
klog.Warningf("Failed to parse remote host from context %q, using default", ctx.Host)
86+
}
87+
} else {
88+
klog.Warningf("Failed to get Docker context info for TLS endpoint: %v", err)
89+
}
90+
}
91+
}
92+
93+
updated, err := kubeconfig.UpdateEndpoint(cname, hostname, port, kubeconfig.PathFromEnv(), kubeconfig.NewExtension())
4194
if err != nil {
4295
exit.Error(reason.HostKubeconfigUpdate, "update config", err)
4396
}
97+
4498
if updated {
45-
out.Step(style.Celebrate, `"{{.context}}" context has been updated to point to {{.hostname}}:{{.port}}`, out.V{"context": cname, "hostname": co.CP.Hostname, "port": co.CP.Port})
99+
if hostname == "localhost" && oci.IsRemoteDockerContext() && oci.IsSSHDockerContext() {
100+
out.Step(style.Celebrate, `"{{.context}}" context has been updated to point to {{.hostname}}:{{.port}} (SSH tunnel to {{.original}})`,
101+
out.V{"context": cname, "hostname": hostname, "port": port, "original": co.CP.Hostname + ":" + strconv.Itoa(co.CP.Port)})
102+
} else if oci.IsRemoteDockerContext() && !oci.IsSSHDockerContext() {
103+
out.Step(style.Celebrate, `"{{.context}}" context has been updated to point to {{.hostname}}:{{.port}} (TLS remote connection)`,
104+
out.V{"context": cname, "hostname": hostname, "port": port})
105+
} else {
106+
out.Step(style.Celebrate, `"{{.context}}" context has been updated to point to {{.hostname}}:{{.port}}`,
107+
out.V{"context": cname, "hostname": hostname, "port": port})
108+
}
46109
} else {
47110
out.Styled(style.Meh, `No changes required for the "{{.context}}" context`, out.V{"context": cname})
48111
}

0 commit comments

Comments
 (0)