From ae9585fc0dc412ea0d3981177c2a4a4bc67a66da Mon Sep 17 00:00:00 2001 From: vyasgun Date: Thu, 25 Apr 2024 14:17:25 +0530 Subject: [PATCH] Make the location for .crc directory configurable - Add a new config key called crc-dir - Initialise Crc base directory variables based on the saved config - New config will take effect after rerunning `crc setup` --- cmd/crc-embedder/cmd/root.go | 2 +- cmd/crc/cmd/root.go | 7 +++--- pkg/crc/config/settings.go | 14 +++++++++-- pkg/crc/config/settings_test.go | 26 ++++++++++++++++++++ pkg/crc/config/validations.go | 7 ++++++ pkg/crc/constants/constants.go | 23 ++++++++++++++++- pkg/crc/preflight/preflight_checks_common.go | 2 +- pkg/crc/validation/validation.go | 10 ++++++++ 8 files changed, 83 insertions(+), 8 deletions(-) diff --git a/cmd/crc-embedder/cmd/root.go b/cmd/crc-embedder/cmd/root.go index 0b08a2e5a0..16533e49b3 100644 --- a/cmd/crc-embedder/cmd/root.go +++ b/cmd/crc-embedder/cmd/root.go @@ -23,7 +23,7 @@ when building the crc executable for release`, } func init() { - err := constants.EnsureBaseDirectoriesExist() + err := constants.EnsureBaseDirectoriesExist("") if err != nil { fmt.Println("CRC base directories are missing: ", err) os.Exit(1) diff --git a/cmd/crc/cmd/root.go b/cmd/crc/cmd/root.go index f257844cab..59d009ee4b 100644 --- a/cmd/crc/cmd/root.go +++ b/cmd/crc/cmd/root.go @@ -46,15 +46,16 @@ var ( ) func init() { - if err := constants.EnsureBaseDirectoriesExist(); err != nil { - logging.Fatal(err.Error()) - } var err error config, viper, err = newConfig() if err != nil { logging.Fatal(err.Error()) } + if err := constants.EnsureBaseDirectoriesExist(crcConfig.GetConfigDir(config)); err != nil { + logging.Fatal(err.Error()) + } + if err := setProxyDefaults(); err != nil { logging.Warn(err.Error()) } diff --git a/pkg/crc/config/settings.go b/pkg/crc/config/settings.go index 9e35402cd8..73ee930bab 100644 --- a/pkg/crc/config/settings.go +++ b/pkg/crc/config/settings.go @@ -37,6 +37,7 @@ const ( EmergencyLogin = "enable-emergency-login" PersistentVolumeSize = "persistent-volume-size" EnableBundleQuayFallback = "enable-bundle-quay-fallback" + CrcDir = "crc-dir" ) func RegisterSettings(cfg *Config) { @@ -141,13 +142,18 @@ func RegisterSettings(cfg *Config) { cfg.AddSetting(EnableBundleQuayFallback, false, ValidateBool, SuccessfullyApplied, "If bundle download from the default location fails, fallback to quay.io (true/false, default: false)") + cfg.AddSetting(CrcDir, constants.GetHomeDir(), validateDirectory, RequiresCRCSetup, + "Location for .crc") - if err := cfg.RegisterNotifier(Preset, presetChanged); err != nil { + if err := cfg.RegisterNotifier(Preset, settingChanged); err != nil { logging.Debugf("Failed to register notifier for Preset: %v", err) } + if err := cfg.RegisterNotifier(CrcDir, settingChanged); err != nil { + logging.Debugf("Failed to register notifier for .crc directory: %v", err) + } } -func presetChanged(cfg *Config, _ string, _ interface{}) { +func settingChanged(cfg *Config, _ string, _ interface{}) { UpdateDefaults(cfg) } @@ -167,6 +173,10 @@ func GetPreset(config Storage) preset.Preset { return preset.ParsePreset(config.Get(Preset).AsString()) } +func GetConfigDir(config Storage) string { + return config.Get(CrcDir).AsString() +} + func defaultNetworkMode() network.Mode { if runtime.GOOS != "linux" { return network.UserNetworkingMode diff --git a/pkg/crc/config/settings_test.go b/pkg/crc/config/settings_test.go index 80f2c35b0a..12d05f5f11 100644 --- a/pkg/crc/config/settings_test.go +++ b/pkg/crc/config/settings_test.go @@ -2,6 +2,7 @@ package config import ( "fmt" + "os" "path/filepath" "testing" @@ -182,3 +183,28 @@ func TestPath(t *testing.T) { IsSecret: false, }, cfg.Get(ProxyCAFile)) } + +func TestDirectory(t *testing.T) { + cfg, err := newInMemoryConfig() + require.NoError(t, err) + + assert.Equal(t, SettingValue{ + Value: constants.GetHomeDir(), + Invalid: false, + IsDefault: true, + IsSecret: false, + }, cfg.Get(CrcDir)) + + tmpDir, err := os.MkdirTemp("", "tempdir") + require.NoError(t, err) + defer os.Remove(tmpDir) + _, err = cfg.Set(CrcDir, tmpDir) + require.NoError(t, err) + + assert.Equal(t, SettingValue{ + Value: tmpDir, + Invalid: false, + IsDefault: false, + IsSecret: false, + }, cfg.Get(CrcDir)) +} diff --git a/pkg/crc/config/validations.go b/pkg/crc/config/validations.go index 42dba5e896..c6bd39a02f 100644 --- a/pkg/crc/config/validations.go +++ b/pkg/crc/config/validations.go @@ -103,6 +103,13 @@ func validatePath(value interface{}) (bool, string) { return true, "" } +func validateDirectory(value interface{}) (bool, string) { + if err := validation.ValidateDirectory(cast.ToString(value)); err != nil { + return false, err.Error() + } + return true, "" +} + // validateHTTPProxy checks if given URI is valid for a HTTP proxy func validateHTTPProxy(value interface{}) (bool, string) { if err := httpproxy.ValidateProxyURL(cast.ToString(value), false); err != nil { diff --git a/pkg/crc/constants/constants.go b/pkg/crc/constants/constants.go index 973989afb7..956e5dc783 100644 --- a/pkg/crc/constants/constants.go +++ b/pkg/crc/constants/constants.go @@ -164,7 +164,8 @@ func GetHomeDir() string { } // EnsureBaseDirectoriesExist creates ~/.crc, ~/.crc/bin and ~/.crc/cache directories if it is not present -func EnsureBaseDirectoriesExist() error { +func EnsureBaseDirectoriesExist(configDir string) error { + initialiseAllDirectories(configDir) baseDirectories := []string{CrcBaseDir, MachineCacheDir, CrcBinDir} for _, baseDir := range baseDirectories { err := os.MkdirAll(baseDir, 0750) @@ -175,6 +176,26 @@ func EnsureBaseDirectoriesExist() error { return nil } +func initialiseAllDirectories(crcDir string) { + if crcDir == "" { + return + } + CrcBaseDir = filepath.Join(crcDir, ".crc") + CrcBinDir = filepath.Join(CrcBaseDir, "bin") + CrcOcBinDir = filepath.Join(CrcBinDir, "oc") + CrcPodmanBinDir = filepath.Join(CrcBinDir, "podman") + CrcSymlinkPath = filepath.Join(CrcBinDir, "crc") + ConfigPath = filepath.Join(CrcBaseDir, ConfigFile) + LogFilePath = filepath.Join(CrcBaseDir, LogFile) + DaemonLogFilePath = filepath.Join(CrcBaseDir, DaemonLogFile) + MachineBaseDir = CrcBaseDir + MachineCacheDir = filepath.Join(MachineBaseDir, "cache") + MachineInstanceDir = filepath.Join(MachineBaseDir, "machines") + DaemonSocketPath = filepath.Join(CrcBaseDir, "crc.sock") + KubeconfigFilePath = filepath.Join(MachineInstanceDir, DefaultName, "kubeconfig") + PasswdFilePath = filepath.Join(MachineInstanceDir, DefaultName, "passwd") +} + func GetPublicKeyPath() string { return filepath.Join(MachineInstanceDir, DefaultName, "id_ecdsa.pub") } diff --git a/pkg/crc/preflight/preflight_checks_common.go b/pkg/crc/preflight/preflight_checks_common.go index 6d7e62d63b..ef09016b43 100644 --- a/pkg/crc/preflight/preflight_checks_common.go +++ b/pkg/crc/preflight/preflight_checks_common.go @@ -21,7 +21,7 @@ import ( 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'", + checkDescription: fmt.Sprintf("Checking if CRC bundle is extracted in %q", bundlePath), check: checkBundleExtracted(bundlePath), fixDescription: "Getting bundle for the CRC executable", fix: fixBundleExtracted(bundlePath, preset, enableBundleQuayFallback), diff --git a/pkg/crc/validation/validation.go b/pkg/crc/validation/validation.go index 4433d3b6da..b9040ea300 100644 --- a/pkg/crc/validation/validation.go +++ b/pkg/crc/validation/validation.go @@ -168,6 +168,16 @@ func ValidatePath(path string) error { return nil } +// ValidateDirectory checks if provided path exists and has sufficient permissions +func ValidateDirectory(path string) error { + file, err := os.CreateTemp(path, "tempfile") + if err != nil { + return &invalidPath{path: path} + } + defer os.Remove(file.Name()) + return nil +} + type imagePullSecret struct { Auths map[string]map[string]interface{} `json:"auths"` }