diff --git a/pkg/crc/constants/constants.go b/pkg/crc/constants/constants.go index 486d9e3d63..57bf8730d8 100644 --- a/pkg/crc/constants/constants.go +++ b/pkg/crc/constants/constants.go @@ -38,6 +38,7 @@ const ( VSockGateway = "192.168.127.1" VsockSSHPort = 2222 + LocalIP = "127.0.0.1" OkdPullSecret = `{"auths":{"fake":{"auth": "Zm9vOmJhcgo="}}}` // #nosec G101 diff --git a/pkg/crc/machine/vsock.go b/pkg/crc/machine/vsock.go index 0257ded53b..190e406852 100644 --- a/pkg/crc/machine/vsock.go +++ b/pkg/crc/machine/vsock.go @@ -78,7 +78,6 @@ const ( virtualMachineIP = "192.168.127.2" hostVirtualIP = "192.168.127.254" internalSSHPort = "22" - localIP = "127.0.0.1" remoteHTTPPort = "80" remoteHTTPSPort = "443" apiPort = "6443" @@ -95,7 +94,7 @@ func vsockPorts(preset crcPreset.Preset, ingressHTTPPort, ingressHTTPSPort uint) exposeRequest := []types.ExposeRequest{ { Protocol: "tcp", - Local: net.JoinHostPort(localIP, strconv.Itoa(constants.VsockSSHPort)), + Local: net.JoinHostPort(constants.LocalIP, strconv.Itoa(constants.VsockSSHPort)), Remote: net.JoinHostPort(virtualMachineIP, internalSSHPort), }, { @@ -110,7 +109,7 @@ func vsockPorts(preset crcPreset.Preset, ingressHTTPPort, ingressHTTPSPort uint) exposeRequest = append(exposeRequest, types.ExposeRequest{ Protocol: "tcp", - Local: net.JoinHostPort(localIP, apiPort), + Local: net.JoinHostPort(constants.LocalIP, apiPort), Remote: net.JoinHostPort(virtualMachineIP, apiPort), }, types.ExposeRequest{ @@ -127,7 +126,7 @@ func vsockPorts(preset crcPreset.Preset, ingressHTTPPort, ingressHTTPSPort uint) exposeRequest = append(exposeRequest, types.ExposeRequest{ Protocol: "tcp", - Local: net.JoinHostPort(localIP, cockpitPort), + Local: net.JoinHostPort(constants.LocalIP, cockpitPort), Remote: net.JoinHostPort(virtualMachineIP, cockpitPort), }) default: diff --git a/pkg/crc/preflight/preflight_checks_common.go b/pkg/crc/preflight/preflight_checks_common.go index 63d26112ad..6d879d240a 100644 --- a/pkg/crc/preflight/preflight_checks_common.go +++ b/pkg/crc/preflight/preflight_checks_common.go @@ -2,12 +2,15 @@ package preflight import ( "fmt" + "net" "os" "path/filepath" + "strconv" "github.com/crc-org/crc/v2/pkg/crc/adminhelper" "github.com/crc-org/crc/v2/pkg/crc/cluster" "github.com/crc-org/crc/v2/pkg/crc/constants" + "github.com/crc-org/crc/v2/pkg/crc/daemonclient" "github.com/crc-org/crc/v2/pkg/crc/logging" "github.com/crc-org/crc/v2/pkg/crc/machine/bundle" crcpreset "github.com/crc-org/crc/v2/pkg/crc/preset" @@ -45,6 +48,17 @@ func memoryCheck(preset crcpreset.Preset) Check { } } +func sshPortCheck() Check { + return Check{ + configKeySuffix: "check-ssh-port", + checkDescription: "Checking SSH port availability", + check: checkSSHPortFree(), + fixDescription: fmt.Sprintf("crc uses %d to run SSH", constants.VsockSSHPort), + flags: NoFix, + labels: None, + } +} + var genericCleanupChecks = []Check{ { cleanupDescription: "Removing CRC Machine Instance directory", @@ -83,6 +97,34 @@ var genericCleanupChecks = []Check{ }, } +func checkSSHPortFree() func() error { + return func() error { + + host := net.JoinHostPort(constants.LocalIP, strconv.Itoa(constants.VsockSSHPort)) + + daemonClient := daemonclient.New() + exposed, err := daemonClient.NetworkClient.List() + if err == nil { + // if port already exported by vsock we could proceed + for _, e := range exposed { + if e.Local == host { + return nil + } + } + } + + server, err := net.Listen("tcp", host) + // if it fails then the port is likely taken + if err != nil { + return fmt.Errorf("port %d already in use: %s", constants.VsockSSHPort, err) + } + server.Close() + + // we successfully used and closed the port + return nil + } +} + func checkBundleExtracted(bundlePath string) func() error { return func() error { logging.Infof("Checking if %s exists", bundlePath) diff --git a/pkg/crc/preflight/preflight_darwin.go b/pkg/crc/preflight/preflight_darwin.go index 20eb146dec..e2155699ba 100644 --- a/pkg/crc/preflight/preflight_darwin.go +++ b/pkg/crc/preflight/preflight_darwin.go @@ -114,6 +114,7 @@ func getChecks(_ network.Mode, bundlePath string, preset crcpreset.Preset, enabl checks = append(checks, bundleCheck(bundlePath, preset, enableBundleQuayFallback)) checks = append(checks, trayLaunchdCleanupChecks...) checks = append(checks, daemonLaunchdChecks...) + checks = append(checks, sshPortCheck()) return checks } diff --git a/pkg/crc/preflight/preflight_darwin_test.go b/pkg/crc/preflight/preflight_darwin_test.go index 1fd8ad1c09..12c2687ac6 100644 --- a/pkg/crc/preflight/preflight_darwin_test.go +++ b/pkg/crc/preflight/preflight_darwin_test.go @@ -13,13 +13,13 @@ import ( func TestCountConfigurationOptions(t *testing.T) { cfg := config.New(config.NewEmptyInMemoryStorage(), config.NewEmptyInMemorySecretStorage()) RegisterSettings(cfg) - assert.Len(t, cfg.AllConfigs(), 11) + assert.Len(t, cfg.AllConfigs(), 12) } func TestCountPreflights(t *testing.T) { - assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 17) - assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 17) + assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 18) + assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 18) - assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 16) - assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 16) + assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 17) + assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 17) } diff --git a/pkg/crc/preflight/preflight_windows.go b/pkg/crc/preflight/preflight_windows.go index e74a94fa19..b6e96c40c7 100644 --- a/pkg/crc/preflight/preflight_windows.go +++ b/pkg/crc/preflight/preflight_windows.go @@ -221,6 +221,7 @@ func getChecks(bundlePath string, preset crcpreset.Preset, enableBundleQuayFallb checks = append(checks, cleanupCheckRemoveCrcVM) checks = append(checks, daemonTaskChecks...) checks = append(checks, adminHelperServiceCheks...) + checks = append(checks, sshPortCheck()) return checks } diff --git a/pkg/crc/preflight/preflight_windows_test.go b/pkg/crc/preflight/preflight_windows_test.go index d785b5d095..603222d6ac 100644 --- a/pkg/crc/preflight/preflight_windows_test.go +++ b/pkg/crc/preflight/preflight_windows_test.go @@ -13,13 +13,13 @@ import ( func TestCountConfigurationOptions(t *testing.T) { cfg := config.New(config.NewEmptyInMemoryStorage(), config.NewEmptyInMemorySecretStorage()) RegisterSettings(cfg) - assert.Len(t, cfg.AllConfigs(), 14) + assert.Len(t, cfg.AllConfigs(), 15) } func TestCountPreflights(t *testing.T) { - assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22) - assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22) + assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23) + assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23) - assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 21) - assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 21) + assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22) + assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22) }