diff --git a/cmd/crc/cmd/start.go b/cmd/crc/cmd/start.go index 87c8044745..a8b7001762 100644 --- a/cmd/crc/cmd/start.go +++ b/cmd/crc/cmd/start.go @@ -81,6 +81,8 @@ func runStart(ctx context.Context) (*types.StartResult, error) { EnableSharedDirs: config.Get(crcConfig.EnableSharedDirs).AsBool(), EmergencyLogin: config.Get(crcConfig.EmergencyLogin).AsBool(), + + EnableBundleQuayFallback: config.Get(crcConfig.EnableBundleQuayFallback).AsBool(), } client := newMachine() diff --git a/pkg/crc/api/handlers.go b/pkg/crc/api/handlers.go index c0ef5d8a10..2224700115 100644 --- a/pkg/crc/api/handlers.go +++ b/pkg/crc/api/handlers.go @@ -119,18 +119,19 @@ func (h *Handler) Start(c *context) error { func getStartConfig(cfg crcConfig.Storage, args client.StartConfig) types.StartConfig { return types.StartConfig{ - BundlePath: cfg.Get(crcConfig.Bundle).AsString(), - Memory: cfg.Get(crcConfig.Memory).AsInt(), - DiskSize: cfg.Get(crcConfig.DiskSize).AsInt(), - CPUs: cfg.Get(crcConfig.CPUs).AsInt(), - NameServer: cfg.Get(crcConfig.NameServer).AsString(), - PullSecret: cluster.NewNonInteractivePullSecretLoader(cfg, args.PullSecretFile), - KubeAdminPassword: cfg.Get(crcConfig.KubeAdminPassword).AsString(), - IngressHTTPPort: cfg.Get(crcConfig.IngressHTTPPort).AsUInt(), - IngressHTTPSPort: cfg.Get(crcConfig.IngressHTTPSPort).AsUInt(), - Preset: crcConfig.GetPreset(cfg), - EnableSharedDirs: cfg.Get(crcConfig.EnableSharedDirs).AsBool(), - EmergencyLogin: cfg.Get(crcConfig.EmergencyLogin).AsBool(), + BundlePath: cfg.Get(crcConfig.Bundle).AsString(), + Memory: cfg.Get(crcConfig.Memory).AsInt(), + DiskSize: cfg.Get(crcConfig.DiskSize).AsInt(), + CPUs: cfg.Get(crcConfig.CPUs).AsInt(), + NameServer: cfg.Get(crcConfig.NameServer).AsString(), + PullSecret: cluster.NewNonInteractivePullSecretLoader(cfg, args.PullSecretFile), + KubeAdminPassword: cfg.Get(crcConfig.KubeAdminPassword).AsString(), + IngressHTTPPort: cfg.Get(crcConfig.IngressHTTPPort).AsUInt(), + IngressHTTPSPort: cfg.Get(crcConfig.IngressHTTPSPort).AsUInt(), + Preset: crcConfig.GetPreset(cfg), + EnableSharedDirs: cfg.Get(crcConfig.EnableSharedDirs).AsBool(), + EmergencyLogin: cfg.Get(crcConfig.EmergencyLogin).AsBool(), + EnableBundleQuayFallback: cfg.Get(crcConfig.EnableBundleQuayFallback).AsBool(), } } diff --git a/pkg/crc/config/settings.go b/pkg/crc/config/settings.go index 503d9f97ed..7d821bb422 100644 --- a/pkg/crc/config/settings.go +++ b/pkg/crc/config/settings.go @@ -12,29 +12,30 @@ import ( ) const ( - Bundle = "bundle" - CPUs = "cpus" - Memory = "memory" - DiskSize = "disk-size" - NameServer = "nameserver" - PullSecretFile = "pull-secret-file" - DisableUpdateCheck = "disable-update-check" - ExperimentalFeatures = "enable-experimental-features" - NetworkMode = "network-mode" - HostNetworkAccess = "host-network-access" - HTTPProxy = "http-proxy" - HTTPSProxy = "https-proxy" - NoProxy = "no-proxy" - ProxyCAFile = "proxy-ca-file" - ConsentTelemetry = "consent-telemetry" - EnableClusterMonitoring = "enable-cluster-monitoring" - KubeAdminPassword = "kubeadmin-password" - Preset = "preset" - EnableSharedDirs = "enable-shared-dirs" - SharedDirPassword = "shared-dir-password" // #nosec G101 - IngressHTTPPort = "ingress-http-port" - IngressHTTPSPort = "ingress-https-port" - EmergencyLogin = "enable-emergency-login" + Bundle = "bundle" + CPUs = "cpus" + Memory = "memory" + DiskSize = "disk-size" + NameServer = "nameserver" + PullSecretFile = "pull-secret-file" + DisableUpdateCheck = "disable-update-check" + ExperimentalFeatures = "enable-experimental-features" + NetworkMode = "network-mode" + HostNetworkAccess = "host-network-access" + HTTPProxy = "http-proxy" + HTTPSProxy = "https-proxy" + NoProxy = "no-proxy" + ProxyCAFile = "proxy-ca-file" + ConsentTelemetry = "consent-telemetry" + EnableClusterMonitoring = "enable-cluster-monitoring" + KubeAdminPassword = "kubeadmin-password" + Preset = "preset" + EnableSharedDirs = "enable-shared-dirs" + SharedDirPassword = "shared-dir-password" // #nosec G101 + IngressHTTPPort = "ingress-http-port" + IngressHTTPSPort = "ingress-https-port" + EmergencyLogin = "enable-emergency-login" + EnableBundleQuayFallback = "enable-bundle-quay-fallback" ) func RegisterSettings(cfg *Config) { @@ -135,6 +136,9 @@ func RegisterSettings(cfg *Config) { cfg.AddSetting(IngressHTTPSPort, constants.OpenShiftIngressHTTPSPort, validatePort, RequiresHTTPSPortChangeWarning, fmt.Sprintf("HTTPS port to use for OpenShift ingress/routes on the host (1024-65535, default: %d)", constants.OpenShiftIngressHTTPSPort)) + cfg.AddSetting(EnableBundleQuayFallback, false, ValidateBool, SuccessfullyApplied, + "Enable pull bundle from quay as fallback (true/false, default: false)") + if err := cfg.RegisterNotifier(Preset, presetChanged); err != nil { logging.Debugf("Failed to register notifier for Preset: %v", err) } diff --git a/pkg/crc/machine/bundle/metadata.go b/pkg/crc/machine/bundle/metadata.go index b3ef400930..de2c58defd 100644 --- a/pkg/crc/machine/bundle/metadata.go +++ b/pkg/crc/machine/bundle/metadata.go @@ -12,6 +12,8 @@ import ( "strings" "time" + "github.com/cavaliergopher/grab/v3" + "github.com/Masterminds/semver/v3" "github.com/crc-org/crc/pkg/crc/constants" "github.com/crc-org/crc/pkg/crc/gpg" @@ -345,7 +347,7 @@ func DownloadDefault(preset crcPreset.Preset) (string, error) { return downloadInfo.Download(constants.GetDefaultBundlePath(preset), 0664) } -func Download(preset crcPreset.Preset, bundleURI string) (string, error) { +func Download(preset crcPreset.Preset, bundleURI string, enableBundleQuayFallback bool) (string, error) { // If we are asked to download // ~/.crc/cache/crc_podman_libvirt_4.1.1.crcbundle, this means we want // are downloading the default bundle for this release. This uses a @@ -353,7 +355,12 @@ func Download(preset crcPreset.Preset, bundleURI string) (string, error) { // bundles, their sha256sums are known and can be checked. if bundleURI == constants.GetDefaultBundlePath(preset) { if preset == crcPreset.OpenShift || preset == crcPreset.Microshift { - return DownloadDefault(preset) + downloadedBundlePath, err := DownloadDefault(preset) + if grab.IsStatusCodeError(errors.Unwrap(err)) && enableBundleQuayFallback { + logging.Info("Unable to download bundle from mirror, falling back to quay") + return image.PullBundle(preset, "") + } + return downloadedBundlePath, err } return image.PullBundle(preset, "") } diff --git a/pkg/crc/machine/start.go b/pkg/crc/machine/start.go index febd16a16f..57825d486b 100644 --- a/pkg/crc/machine/start.go +++ b/pkg/crc/machine/start.go @@ -45,7 +45,7 @@ import ( const minimumMemoryForMonitoring = 14336 -func getCrcBundleInfo(preset crcPreset.Preset, bundleName, bundlePath string) (*bundle.CrcBundleInfo, error) { +func getCrcBundleInfo(preset crcPreset.Preset, bundleName, bundlePath string, enableBundleQuayFallback bool) (*bundle.CrcBundleInfo, error) { bundleInfo, err := bundle.Use(bundleName) if err == nil { logging.Infof("Loading bundle: %s...", bundleName) @@ -53,7 +53,7 @@ func getCrcBundleInfo(preset crcPreset.Preset, bundleName, bundlePath string) (* } logging.Debugf("Failed to load bundle %s: %v", bundleName, err) logging.Infof("Downloading bundle: %s...", bundleName) - bundlePath, err = bundle.Download(preset, bundlePath) + bundlePath, err = bundle.Download(preset, bundlePath, enableBundleQuayFallback) if err != nil { return nil, err } @@ -283,7 +283,7 @@ func (client *client) Start(ctx context.Context, startConfig types.StartConfig) } bundleName := bundle.GetBundleNameWithoutExtension(bundle.GetBundleNameFromURI(startConfig.BundlePath)) - crcBundleMetadata, err := getCrcBundleInfo(startConfig.Preset, bundleName, startConfig.BundlePath) + crcBundleMetadata, err := getCrcBundleInfo(startConfig.Preset, bundleName, startConfig.BundlePath, startConfig.EnableBundleQuayFallback) if err != nil { return nil, errors.Wrap(err, "Error getting bundle metadata") } diff --git a/pkg/crc/machine/types/types.go b/pkg/crc/machine/types/types.go index 8373f5439f..5979562387 100644 --- a/pkg/crc/machine/types/types.go +++ b/pkg/crc/machine/types/types.go @@ -40,6 +40,9 @@ type StartConfig struct { // Enable emergency login EmergencyLogin bool + + // Enable bundle quay fallback + EnableBundleQuayFallback bool } type ClusterConfig struct { diff --git a/pkg/crc/preflight/preflight.go b/pkg/crc/preflight/preflight.go index 6177df7dd3..f973dff688 100644 --- a/pkg/crc/preflight/preflight.go +++ b/pkg/crc/preflight/preflight.go @@ -156,8 +156,9 @@ func getPreflightChecksHelper(config crcConfig.Storage) []Check { mode := crcConfig.GetNetworkMode(config) bundlePath := config.Get(crcConfig.Bundle).AsString() preset := crcConfig.GetPreset(config) + enableBundleQuayFallback := config.Get(crcConfig.EnableBundleQuayFallback).AsBool() logging.Infof("Using bundle path %s", bundlePath) - return getPreflightChecks(experimentalFeatures, mode, bundlePath, preset) + return getPreflightChecks(experimentalFeatures, mode, bundlePath, preset, enableBundleQuayFallback) } // StartPreflightChecks performs the preflight checks before starting the cluster diff --git a/pkg/crc/preflight/preflight_checks_common.go b/pkg/crc/preflight/preflight_checks_common.go index 45d3f6c080..76d8bf70fa 100644 --- a/pkg/crc/preflight/preflight_checks_common.go +++ b/pkg/crc/preflight/preflight_checks_common.go @@ -18,13 +18,13 @@ import ( "github.com/pkg/errors" ) -func bundleCheck(bundlePath string, preset crcpreset.Preset) Check { +func bundleCheck(bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) Check { return Check{ configKeySuffix: "check-bundle-extracted", checkDescription: "Checking if CRC bundle is extracted in '$HOME/.crc'", check: checkBundleExtracted(bundlePath), fixDescription: "Getting bundle for the CRC executable", - fix: fixBundleExtracted(bundlePath, preset), + fix: fixBundleExtracted(bundlePath, preset, enableBundleQuayFallback), flags: SetupOnly, labels: None, @@ -96,7 +96,7 @@ func checkBundleExtracted(bundlePath string) func() error { } } -func fixBundleExtracted(bundlePath string, preset crcpreset.Preset) func() error { +func fixBundleExtracted(bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) func() error { // Should be removed after 1.19 release // This check will ensure correct mode for `~/.crc/cache` directory // in case it exists. @@ -123,7 +123,7 @@ func fixBundleExtracted(bundlePath string, preset crcpreset.Preset) func() error var err error logging.Infof("Downloading bundle: %s...", bundlePath) - if bundlePath, err = bundle.Download(preset, bundlePath); err != nil { + if bundlePath, err = bundle.Download(preset, bundlePath, enableBundleQuayFallback); err != nil { return err } diff --git a/pkg/crc/preflight/preflight_darwin.go b/pkg/crc/preflight/preflight_darwin.go index 53927c9974..9683b665bf 100644 --- a/pkg/crc/preflight/preflight_darwin.go +++ b/pkg/crc/preflight/preflight_darwin.go @@ -99,10 +99,10 @@ var daemonLaunchdChecks = []Check{ // Passing 'SystemNetworkingMode' to getPreflightChecks currently achieves this // as there are no user networking specific checks func getAllPreflightChecks() []Check { - return getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift) + return getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false) } -func getChecks(_ network.Mode, bundlePath string, preset crcpreset.Preset) []Check { +func getChecks(_ network.Mode, bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check { checks := []Check{} checks = append(checks, nonWinPreflightChecks...) @@ -111,16 +111,16 @@ func getChecks(_ network.Mode, bundlePath string, preset crcpreset.Preset) []Che checks = append(checks, genericCleanupChecks...) checks = append(checks, vfkitPreflightChecks...) checks = append(checks, resolverPreflightChecks...) - checks = append(checks, bundleCheck(bundlePath, preset)) + checks = append(checks, bundleCheck(bundlePath, preset, enableBundleQuayFallback)) checks = append(checks, trayLaunchdCleanupChecks...) checks = append(checks, daemonLaunchdChecks...) return checks } -func getPreflightChecks(_ bool, mode network.Mode, bundlePath string, preset crcpreset.Preset) []Check { +func getPreflightChecks(_ bool, mode network.Mode, bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check { filter := newFilter() filter.SetNetworkMode(mode) - return filter.Apply(getChecks(mode, bundlePath, preset)) + return filter.Apply(getChecks(mode, bundlePath, preset, enableBundleQuayFallback)) } diff --git a/pkg/crc/preflight/preflight_darwin_test.go b/pkg/crc/preflight/preflight_darwin_test.go index 872d8d3994..400e42c986 100644 --- a/pkg/crc/preflight/preflight_darwin_test.go +++ b/pkg/crc/preflight/preflight_darwin_test.go @@ -17,9 +17,9 @@ func TestCountConfigurationOptions(t *testing.T) { } func TestCountPreflights(t *testing.T) { - assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 17) - assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 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), 17) - assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 16) - assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 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), 16) } diff --git a/pkg/crc/preflight/preflight_linux.go b/pkg/crc/preflight/preflight_linux.go index c8bbd7724c..62a2688e01 100644 --- a/pkg/crc/preflight/preflight_linux.go +++ b/pkg/crc/preflight/preflight_linux.go @@ -343,26 +343,26 @@ func getAllPreflightChecks() []Check { filter.SetDistro(distro()) filter.SetSystemdUser(distro()) - return filter.Apply(getChecks(distro(), constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift)) + return filter.Apply(getChecks(distro(), constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false)) } -func getPreflightChecks(_ bool, networkMode network.Mode, bundlePath string, preset crcpreset.Preset) []Check { +func getPreflightChecks(_ bool, networkMode network.Mode, bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check { usingSystemdResolved := checkSystemdResolvedIsRunning() - return getPreflightChecksForDistro(distro(), networkMode, usingSystemdResolved == nil, bundlePath, preset) + return getPreflightChecksForDistro(distro(), networkMode, usingSystemdResolved == nil, bundlePath, preset, enableBundleQuayFallback) } -func getPreflightChecksForDistro(distro *linux.OsRelease, networkMode network.Mode, usingSystemdResolved bool, bundlePath string, preset crcpreset.Preset) []Check { +func getPreflightChecksForDistro(distro *linux.OsRelease, networkMode network.Mode, usingSystemdResolved bool, bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check { filter := newFilter() filter.SetDistro(distro) filter.SetSystemdUser(distro) filter.SetNetworkMode(networkMode) filter.SetSystemdResolved(usingSystemdResolved) - return filter.Apply(getChecks(distro, bundlePath, preset)) + return filter.Apply(getChecks(distro, bundlePath, preset, enableBundleQuayFallback)) } -func getChecks(distro *linux.OsRelease, bundlePath string, preset crcpreset.Preset) []Check { +func getChecks(distro *linux.OsRelease, bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check { var checks []Check checks = append(checks, nonWinPreflightChecks...) checks = append(checks, wsl2PreflightCheck) @@ -376,7 +376,7 @@ func getChecks(distro *linux.OsRelease, bundlePath string, preset crcpreset.Pres checks = append(checks, dnsmasqPreflightChecks...) checks = append(checks, libvirtNetworkPreflightChecks...) checks = append(checks, vsockPreflightCheck) - checks = append(checks, bundleCheck(bundlePath, preset)) + checks = append(checks, bundleCheck(bundlePath, preset, enableBundleQuayFallback)) return checks } diff --git a/pkg/crc/preflight/preflight_linux_test.go b/pkg/crc/preflight/preflight_linux_test.go index a29a55b7b5..cb08d5da2a 100644 --- a/pkg/crc/preflight/preflight_linux_test.go +++ b/pkg/crc/preflight/preflight_linux_test.go @@ -509,7 +509,7 @@ func assertFuncEqual(t *testing.T, func1 interface{}, func2 interface{}) { } func assertExpectedPreflights(t *testing.T, distro *crcos.OsRelease, networkMode network.Mode, systemdResolved bool) { - preflights := getPreflightChecksForDistro(distro, networkMode, systemdResolved, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift) + preflights := getPreflightChecksForDistro(distro, networkMode, systemdResolved, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false) var expected checkListForDistro for _, expected = range checkListForDistros { if expected.distro == distro && expected.networkMode == networkMode && expected.systemdResolved == systemdResolved { diff --git a/pkg/crc/preflight/preflight_windows.go b/pkg/crc/preflight/preflight_windows.go index bcfa9523f1..40eef0c6c0 100644 --- a/pkg/crc/preflight/preflight_windows.go +++ b/pkg/crc/preflight/preflight_windows.go @@ -200,17 +200,17 @@ func checkVsock() error { // Passing 'UserNetworkingMode' to getPreflightChecks currently achieves this // as there are no system networking specific checks func getAllPreflightChecks() []Check { - return getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift) + return getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false) } -func getChecks(bundlePath string, preset crcpreset.Preset) []Check { +func getChecks(bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check { checks := []Check{} checks = append(checks, memoryCheck(preset)) checks = append(checks, hypervPreflightChecks...) checks = append(checks, crcUsersGroupExistsCheck) checks = append(checks, userPartOfCrcUsersAndHypervAdminsGroupCheck) checks = append(checks, vsockChecks...) - checks = append(checks, bundleCheck(bundlePath, preset)) + checks = append(checks, bundleCheck(bundlePath, preset, enableBundleQuayFallback)) checks = append(checks, genericCleanupChecks...) checks = append(checks, cleanupCheckRemoveCrcVM) checks = append(checks, daemonTaskChecks...) @@ -218,9 +218,9 @@ func getChecks(bundlePath string, preset crcpreset.Preset) []Check { return checks } -func getPreflightChecks(_ bool, networkMode network.Mode, bundlePath string, preset crcpreset.Preset) []Check { +func getPreflightChecks(_ bool, networkMode network.Mode, bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check { filter := newFilter() filter.SetNetworkMode(networkMode) - return filter.Apply(getChecks(bundlePath, preset)) + return filter.Apply(getChecks(bundlePath, preset, enableBundleQuayFallback)) } diff --git a/pkg/crc/preflight/preflight_windows_test.go b/pkg/crc/preflight/preflight_windows_test.go index 8e78aa0352..cd6cd39903 100644 --- a/pkg/crc/preflight/preflight_windows_test.go +++ b/pkg/crc/preflight/preflight_windows_test.go @@ -17,9 +17,9 @@ func TestCountConfigurationOptions(t *testing.T) { } func TestCountPreflights(t *testing.T) { - assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 21) - assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 21) + assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 21) + assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 21) - assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 20) - assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift), 20) + assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 20) + assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 20) }