Skip to content

Commit 2356559

Browse files
committed
Issue #2068 Add disk space preflight check
Add a preflight check that validates sufficient free disk space (43 GiB) before downloading/extracting the CRC bundle. Walk up to the nearest existing ancestor directory so the check works on fresh installs where ~/.crc/cache has not been created yet.
1 parent 9fe03b5 commit 2356559

13 files changed

+123
-10
lines changed

.github/workflows/macos-installer.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ jobs:
4242
with:
4343
name: macOS Installer (${{ matrix.os }})
4444
path: "./out/macos-universal/crc-macos-installer.pkg"
45+
- name: Free disk space for crc setup
46+
uses: palmsoftware/quick-cleanup@v0
47+
with:
48+
cleanup-mode: aggressive
4549
- name: Install crc pkg
4650
run: sudo installer -pkg out/macos-universal/crc-macos-installer.pkg -target /
4751
- name: Set microshift preset as part of config

pkg/crc/constants/constants.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ const (
1919

2020
DefaultPersistentVolumeSize = 15
2121

22+
// EstimatedCompressedBundleSize is the approximate size in GiB of the compressed CRC bundle download.
23+
EstimatedCompressedBundleSize = 12
24+
25+
// MinimumDiskSpaceForSetup is the minimum free disk space required to download and extract the bundle.
26+
// During extraction the compressed bundle and the extracted disk image coexist on disk,
27+
// so we need DefaultDiskSize + EstimatedCompressedBundleSize of free space.
28+
MinimumDiskSpaceForSetup = (DefaultDiskSize + EstimatedCompressedBundleSize) * 1024 * 1024 * 1024
29+
2230
DefaultSSHUser = "core"
2331
DefaultSSHPort = 22
2432

pkg/crc/preflight/preflight_checks_common.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ func memoryCheck(preset crcpreset.Preset) Check {
4848
}
4949
}
5050

51+
func diskSpaceCheck() Check {
52+
return Check{
53+
configKeySuffix: "check-disk-space",
54+
checkDescription: "Checking if enough disk space is available for the bundle",
55+
check: func() error {
56+
return validation.ValidateEnoughFreeSpace(constants.GetHomeDir(), constants.MinimumDiskSpaceForSetup)
57+
},
58+
fixDescription: fmt.Sprintf("crc requires at least %s of free disk space to unpack the bundle",
59+
units.BytesSize(float64(constants.MinimumDiskSpaceForSetup))),
60+
flags: NoFix,
61+
62+
labels: None,
63+
}
64+
}
65+
5166
var genericCleanupChecks = []Check{
5267
{
5368
cleanupDescription: "Removing CRC Machine Instance directory",

pkg/crc/preflight/preflight_darwin.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ func getChecks(_ network.Mode, bundlePath string, preset crcpreset.Preset, enabl
119119
checks = append(checks, nonWinPreflightChecks...)
120120
checks = append(checks, genericPreflightChecks(preset)...)
121121
checks = append(checks, memoryCheck(preset))
122+
checks = append(checks, diskSpaceCheck())
122123
checks = append(checks, genericCleanupChecks...)
123124
checks = append(checks, vfkitPreflightChecks...)
124125
checks = append(checks, resolverPreflightChecks...)

pkg/crc/preflight/preflight_darwin_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import (
1313
func TestCountConfigurationOptions(t *testing.T) {
1414
cfg := config.New(config.NewEmptyInMemoryStorage(), config.NewEmptyInMemorySecretStorage())
1515
RegisterSettings(cfg)
16-
assert.Len(t, cfg.AllConfigs(), 13)
16+
assert.Len(t, cfg.AllConfigs(), 14)
1717
}
1818

1919
func TestCountPreflights(t *testing.T) {
20-
assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 20)
21-
assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 20)
20+
assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 21)
21+
assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 21)
2222

23-
assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 19)
24-
assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 19)
23+
assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 20)
24+
assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 20)
2525
}

pkg/crc/preflight/preflight_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ func getChecks(distro *linux.OsRelease, bundlePath string, preset crcpreset.Pres
367367
checks = append(checks, wsl2PreflightCheck)
368368
checks = append(checks, genericPreflightChecks(preset)...)
369369
checks = append(checks, memoryCheck(preset))
370+
checks = append(checks, diskSpaceCheck())
370371
checks = append(checks, genericCleanupChecks...)
371372
checks = append(checks, libvirtPreflightChecks(distro)...)
372373
checks = append(checks, ubuntuPreflightChecks...)

pkg/crc/preflight/preflight_linux_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ var checkListForDistros = []checkListForDistro{
7070
{check: checkSupportedCPUArch},
7171
{check: checkCrcSymlink},
7272
{configKeySuffix: "check-ram"},
73+
{configKeySuffix: "check-disk-space"},
7374
{cleanup: removeCRCMachinesDir},
7475
{cleanup: removeAllLogs},
7576
{cleanup: cluster.ForgetPullSecret},
@@ -110,6 +111,7 @@ var checkListForDistros = []checkListForDistro{
110111
{check: checkSupportedCPUArch},
111112
{check: checkCrcSymlink},
112113
{configKeySuffix: "check-ram"},
114+
{configKeySuffix: "check-disk-space"},
113115
{cleanup: removeCRCMachinesDir},
114116
{cleanup: removeAllLogs},
115117
{cleanup: cluster.ForgetPullSecret},
@@ -149,6 +151,7 @@ var checkListForDistros = []checkListForDistro{
149151
{check: checkSupportedCPUArch},
150152
{check: checkCrcSymlink},
151153
{configKeySuffix: "check-ram"},
154+
{configKeySuffix: "check-disk-space"},
152155
{cleanup: removeCRCMachinesDir},
153156
{cleanup: removeAllLogs},
154157
{cleanup: cluster.ForgetPullSecret},
@@ -182,6 +185,7 @@ var checkListForDistros = []checkListForDistro{
182185
{check: checkSupportedCPUArch},
183186
{check: checkCrcSymlink},
184187
{configKeySuffix: "check-ram"},
188+
{configKeySuffix: "check-disk-space"},
185189
{cleanup: removeCRCMachinesDir},
186190
{cleanup: removeAllLogs},
187191
{cleanup: cluster.ForgetPullSecret},
@@ -222,6 +226,7 @@ var checkListForDistros = []checkListForDistro{
222226
{check: checkSupportedCPUArch},
223227
{check: checkCrcSymlink},
224228
{configKeySuffix: "check-ram"},
229+
{configKeySuffix: "check-disk-space"},
225230
{cleanup: removeCRCMachinesDir},
226231
{cleanup: removeAllLogs},
227232
{cleanup: cluster.ForgetPullSecret},
@@ -261,6 +266,7 @@ var checkListForDistros = []checkListForDistro{
261266
{check: checkSupportedCPUArch},
262267
{check: checkCrcSymlink},
263268
{configKeySuffix: "check-ram"},
269+
{configKeySuffix: "check-disk-space"},
264270
{cleanup: removeCRCMachinesDir},
265271
{cleanup: removeAllLogs},
266272
{cleanup: cluster.ForgetPullSecret},
@@ -294,6 +300,7 @@ var checkListForDistros = []checkListForDistro{
294300
{check: checkSupportedCPUArch},
295301
{check: checkCrcSymlink},
296302
{configKeySuffix: "check-ram"},
303+
{configKeySuffix: "check-disk-space"},
297304
{cleanup: removeCRCMachinesDir},
298305
{cleanup: removeAllLogs},
299306
{cleanup: cluster.ForgetPullSecret},
@@ -334,6 +341,7 @@ var checkListForDistros = []checkListForDistro{
334341
{check: checkSupportedCPUArch},
335342
{check: checkCrcSymlink},
336343
{configKeySuffix: "check-ram"},
344+
{configKeySuffix: "check-disk-space"},
337345
{cleanup: removeCRCMachinesDir},
338346
{cleanup: removeAllLogs},
339347
{cleanup: cluster.ForgetPullSecret},
@@ -373,6 +381,7 @@ var checkListForDistros = []checkListForDistro{
373381
{check: checkSupportedCPUArch},
374382
{check: checkCrcSymlink},
375383
{configKeySuffix: "check-ram"},
384+
{configKeySuffix: "check-disk-space"},
376385
{cleanup: removeCRCMachinesDir},
377386
{cleanup: removeAllLogs},
378387
{cleanup: cluster.ForgetPullSecret},
@@ -406,6 +415,7 @@ var checkListForDistros = []checkListForDistro{
406415
{check: checkSupportedCPUArch},
407416
{check: checkCrcSymlink},
408417
{configKeySuffix: "check-ram"},
418+
{configKeySuffix: "check-disk-space"},
409419
{cleanup: removeCRCMachinesDir},
410420
{cleanup: removeAllLogs},
411421
{cleanup: cluster.ForgetPullSecret},
@@ -447,6 +457,7 @@ var checkListForDistros = []checkListForDistro{
447457
{check: checkSupportedCPUArch},
448458
{check: checkCrcSymlink},
449459
{configKeySuffix: "check-ram"},
460+
{configKeySuffix: "check-disk-space"},
450461
{cleanup: removeCRCMachinesDir},
451462
{cleanup: removeAllLogs},
452463
{cleanup: cluster.ForgetPullSecret},
@@ -487,6 +498,7 @@ var checkListForDistros = []checkListForDistro{
487498
{check: checkSupportedCPUArch},
488499
{check: checkCrcSymlink},
489500
{configKeySuffix: "check-ram"},
501+
{configKeySuffix: "check-disk-space"},
490502
{cleanup: removeCRCMachinesDir},
491503
{cleanup: removeAllLogs},
492504
{cleanup: cluster.ForgetPullSecret},

pkg/crc/preflight/preflight_windows.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ func getAllPreflightChecks() []Check {
218218
func getChecks(bundlePath string, preset crcpreset.Preset, enableBundleQuayFallback bool) []Check {
219219
checks := []Check{}
220220
checks = append(checks, memoryCheck(preset))
221+
checks = append(checks, diskSpaceCheck())
221222
checks = append(checks, hypervPreflightChecks...)
222223
checks = append(checks, crcUsersGroupExistsCheck)
223224
checks = append(checks, userPartOfCrcUsersAndHypervAdminsGroupCheck)

pkg/crc/preflight/preflight_windows_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ import (
1313
func TestCountConfigurationOptions(t *testing.T) {
1414
cfg := config.New(config.NewEmptyInMemoryStorage(), config.NewEmptyInMemorySecretStorage())
1515
RegisterSettings(cfg)
16-
assert.Len(t, cfg.AllConfigs(), 15)
16+
assert.Len(t, cfg.AllConfigs(), 16)
1717
}
1818

1919
func TestCountPreflights(t *testing.T) {
20-
assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22)
21-
assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 22)
20+
assert.Len(t, getPreflightChecks(false, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23)
21+
assert.Len(t, getPreflightChecks(true, network.SystemNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23)
2222

23-
assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23)
24-
assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 23)
23+
assert.Len(t, getPreflightChecks(false, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 24)
24+
assert.Len(t, getPreflightChecks(true, network.UserNetworkingMode, constants.GetDefaultBundlePath(preset.OpenShift), preset.OpenShift, false), 24)
2525
}

pkg/crc/validation/validation.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,23 @@ func ValidateEnoughMemory(value strongunits.MiB) error {
6464
return nil
6565
}
6666

67+
// ValidateEnoughFreeSpace checks if enough free disk space is available at the given path.
68+
func ValidateEnoughFreeSpace(path string, requiredBytes uint64) error {
69+
freeSpace, err := freeDiskSpace(path)
70+
if err != nil {
71+
logging.Debugf("Unable to determine free disk space for %s: %v", path, err)
72+
return nil // Don't block on error - fail open
73+
}
74+
logging.Debugf("Free disk space at %s: %d bytes", path, freeSpace)
75+
if freeSpace < requiredBytes {
76+
return fmt.Errorf("only %s of disk space free at %s (%s required)",
77+
units.BytesSize(float64(freeSpace)),
78+
path,
79+
units.BytesSize(float64(requiredBytes)))
80+
}
81+
return nil
82+
}
83+
6784
// ValidateBundlePath checks if the provided bundle path exist
6885
func ValidateBundlePath(bundlePath string, preset crcpreset.Preset) error {
6986
logging.Debugf("Got bundle path: %s", bundlePath)

0 commit comments

Comments
 (0)